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