1 /*******************************************************************************
2     Copyright (c) 2015-2023 NVIDIA Corporation
3 
4     Permission is hereby granted, free of charge, to any person obtaining a copy
5     of this software and associated documentation files (the "Software"), to
6     deal in the Software without restriction, including without limitation the
7     rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8     sell copies of the Software, and to permit persons to whom the Software is
9     furnished to do so, subject to the following conditions:
10 
11         The above copyright notice and this permission notice shall be
12         included in all copies or substantial portions of the Software.
13 
14     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20     DEALINGS IN THE SOFTWARE.
21 
22 *******************************************************************************/
23 
24 #ifndef __UVM_RM_MEM_H__
25 #define __UVM_RM_MEM_H__
26 
27 #include "uvm_forward_decl.h"
28 #include "uvm_processors.h"
29 #include "uvm_test_ioctl.h"
30 #include "uvm_hal_types.h"
31 
32 typedef enum
33 {
34     UVM_RM_MEM_TYPE_GPU,
35     UVM_RM_MEM_TYPE_SYS,
36 } uvm_rm_mem_type_t;
37 
38 // Abstraction for memory allocations done through the UVM-RM interface
39 struct uvm_rm_mem_struct
40 {
41     // Type of the memory
42     uvm_rm_mem_type_t type;
43 
44     // Mask of processors the memory is mapped on
45     uvm_processor_mask_t mapped_on;
46 
47     // VA of the memory on the UVM internal address space of each processor. If
48     // the memory has not been mapped on a given processor, the VA is zero.
49     NvU64 vas[UVM_ID_MAX_PROCESSORS];
50 
51     // VA of the memory in the proxy address space of each processor. If
52     // the memory has not been mapped on a given processor, the VA is zero.
53     // If the memory is mapped on the proxy address space of a processor, then
54     // it must be mapped on UVM's internal address space.
55     //
56     // This array is only allocated in SR-IOV heavy. It is sized, and indexed,
57     // as the 'vas' array.
58     NvU64 *proxy_vas;
59 
60     // The GPU the allocation originated from
61     uvm_gpu_t *gpu_owner;
62 
63     // Size of the allocation
64     NvLength size;
65 };
66 
67 // Allocate memory of the given type and size in the GPU's UVM internal address
68 // space, and (in SR-IOV heavy) map it on the proxy address space as well.
69 //
70 // The GPU cannot be NULL and the memory is going to mapped on the GPU for the
71 // lifetime of the allocation. For sysmem allocations other GPUs can have a
72 // mapping created and removed dynamically with the uvm_rm_mem_(un)map_gpu()
73 // functions.
74 //
75 // Alignment affects only the GPU VA mapping. If gpu_alignment is 0, then 4K
76 // alignment is enforced.
77 //
78 // Locking:
79 //  - Internally acquires:
80 //    - RM API lock
81 //    - RM GPUs lock
82 NV_STATUS uvm_rm_mem_alloc(uvm_gpu_t *gpu,
83                            uvm_rm_mem_type_t type,
84                            NvLength size,
85                            NvU64 gpu_alignment,
86                            uvm_rm_mem_t **rm_mem_out);
87 
88 // Free the memory.
89 // Clear all mappings and free the memory
90 //
91 // Locking same as uvm_rm_mem_alloc()
92 void uvm_rm_mem_free(uvm_rm_mem_t *rm_mem);
93 
94 // Map/Unmap on the CPU
95 // Locking same as uvm_rm_mem_alloc()
96 NV_STATUS uvm_rm_mem_map_cpu(uvm_rm_mem_t *rm_mem);
97 void uvm_rm_mem_unmap_cpu(uvm_rm_mem_t *rm_mem);
98 
99 // Shortcut for uvm_rm_mem_alloc() + uvm_rm_mem_map_cpu().
100 // The function fails and nothing is allocated if any of the intermediate steps
101 // fail.
102 //
103 // Locking same as uvm_rm_mem_alloc()
104 NV_STATUS uvm_rm_mem_alloc_and_map_cpu(uvm_gpu_t *gpu,
105                                        uvm_rm_mem_type_t type,
106                                        NvLength size,
107                                        NvU64 gpu_alignment,
108                                        uvm_rm_mem_t **rm_mem_out);
109 
110 // Shortcut for uvm_rm_mem_alloc_and_map_cpu() + uvm_rm_mem_map_all_gpus()
111 // The function fails and nothing is allocated if any of the intermediate steps
112 // fail.
113 //
114 // Locking same as uvm_rm_mem_alloc()
115 NV_STATUS uvm_rm_mem_alloc_and_map_all(uvm_gpu_t *gpu,
116                                        uvm_rm_mem_type_t type,
117                                        NvLength size,
118                                        NvU64 gpu_alignment,
119                                        uvm_rm_mem_t **rm_mem_out);
120 
121 // Map/Unmap on UVM's internal address space of a GPU. In SR-IOV heavy the
122 // operation is also applied on the GPU's proxy address space.
123 //
124 // Mapping/unmapping on the GPU owner, or mapping on an already mapped GPU, are
125 // no-ops. Mapping/unmapping on a GPU different from the owner is only supported
126 // for system memory.
127 //
128 // Locking same as uvm_rm_mem_alloc()
129 NV_STATUS uvm_rm_mem_map_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu, NvU64 gpu_alignment);
130 void uvm_rm_mem_unmap_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
131 
132 // Map on UVM's internal address space of all GPUs retained by the UVM driver
133 // that do not yet have this allocation mapped. In SR-IOV heavy the memory is
134 // also mapped on the proxy address space of all GPUs.
135 //
136 // Locking same as uvm_rm_mem_alloc()
137 NV_STATUS uvm_rm_mem_map_all_gpus(uvm_rm_mem_t *rm_mem, NvU64 gpu_alignment);
138 
139 // Get the CPU VA, GPU VA (UVM internal/kernel address space), or GPU (proxy
140 // address space)
141 void *uvm_rm_mem_get_cpu_va(uvm_rm_mem_t *rm_mem);
142 NvU64 uvm_rm_mem_get_gpu_uvm_va(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
143 NvU64 uvm_rm_mem_get_gpu_proxy_va(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
144 
145 // Get the GPU VA of the given memory in UVM's internal address space (if the
146 // flag is false), or proxy address space (if flag is true).
147 uvm_gpu_address_t uvm_rm_mem_get_gpu_va(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu, bool is_proxy_va_space);
148 
149 // Query if the memory is mapped on the CPU, GPU (UVM internal/kernel address
150 // space), or GPU (proxy address space)
151 bool uvm_rm_mem_mapped_on_cpu(uvm_rm_mem_t *rm_mem);
152 bool uvm_rm_mem_mapped_on_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
153 bool uvm_rm_mem_mapped_on_gpu_proxy(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
154 
155 #endif // __UVM_RM_MEM_H__
156