11739a20eSAndy Ritger /*******************************************************************************
2*91676d66SBernhard Stoeckner     Copyright (c) 2015-2023 NVIDIA Corporation
31739a20eSAndy Ritger 
41739a20eSAndy Ritger     Permission is hereby granted, free of charge, to any person obtaining a copy
51739a20eSAndy Ritger     of this software and associated documentation files (the "Software"), to
61739a20eSAndy Ritger     deal in the Software without restriction, including without limitation the
71739a20eSAndy Ritger     rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
81739a20eSAndy Ritger     sell copies of the Software, and to permit persons to whom the Software is
91739a20eSAndy Ritger     furnished to do so, subject to the following conditions:
101739a20eSAndy Ritger 
111739a20eSAndy Ritger         The above copyright notice and this permission notice shall be
121739a20eSAndy Ritger         included in all copies or substantial portions of the Software.
131739a20eSAndy Ritger 
141739a20eSAndy Ritger     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151739a20eSAndy Ritger     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161739a20eSAndy Ritger     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
171739a20eSAndy Ritger     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
181739a20eSAndy Ritger     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
191739a20eSAndy Ritger     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
201739a20eSAndy Ritger     DEALINGS IN THE SOFTWARE.
211739a20eSAndy Ritger 
221739a20eSAndy Ritger *******************************************************************************/
231739a20eSAndy Ritger 
241739a20eSAndy Ritger #ifndef __UVM_RM_MEM_H__
251739a20eSAndy Ritger #define __UVM_RM_MEM_H__
261739a20eSAndy Ritger 
271739a20eSAndy Ritger #include "uvm_forward_decl.h"
281739a20eSAndy Ritger #include "uvm_processors.h"
291739a20eSAndy Ritger #include "uvm_test_ioctl.h"
30eb5c7665SAndy Ritger #include "uvm_hal_types.h"
311739a20eSAndy Ritger 
321739a20eSAndy Ritger typedef enum
331739a20eSAndy Ritger {
341739a20eSAndy Ritger     UVM_RM_MEM_TYPE_GPU,
351739a20eSAndy Ritger     UVM_RM_MEM_TYPE_SYS,
361739a20eSAndy Ritger } uvm_rm_mem_type_t;
371739a20eSAndy Ritger 
381739a20eSAndy Ritger // Abstraction for memory allocations done through the UVM-RM interface
391739a20eSAndy Ritger struct uvm_rm_mem_struct
401739a20eSAndy Ritger {
411739a20eSAndy Ritger     // Type of the memory
421739a20eSAndy Ritger     uvm_rm_mem_type_t type;
431739a20eSAndy Ritger 
441739a20eSAndy Ritger     // Mask of processors the memory is mapped on
45*91676d66SBernhard Stoeckner     uvm_processor_mask_t mapped_on;
461739a20eSAndy Ritger 
471739a20eSAndy Ritger     // VA of the memory on the UVM internal address space of each processor. If
481739a20eSAndy Ritger     // the memory has not been mapped on a given processor, the VA is zero.
49*91676d66SBernhard Stoeckner     NvU64 vas[UVM_ID_MAX_PROCESSORS];
501739a20eSAndy Ritger 
511739a20eSAndy Ritger     // VA of the memory in the proxy address space of each processor. If
521739a20eSAndy Ritger     // the memory has not been mapped on a given processor, the VA is zero.
531739a20eSAndy Ritger     // If the memory is mapped on the proxy address space of a processor, then
541739a20eSAndy Ritger     // it must be mapped on UVM's internal address space.
551739a20eSAndy Ritger     //
561739a20eSAndy Ritger     // This array is only allocated in SR-IOV heavy. It is sized, and indexed,
571739a20eSAndy Ritger     // as the 'vas' array.
581739a20eSAndy Ritger     NvU64 *proxy_vas;
591739a20eSAndy Ritger 
601739a20eSAndy Ritger     // The GPU the allocation originated from
611739a20eSAndy Ritger     uvm_gpu_t *gpu_owner;
621739a20eSAndy Ritger 
631739a20eSAndy Ritger     // Size of the allocation
641739a20eSAndy Ritger     NvLength size;
651739a20eSAndy Ritger };
661739a20eSAndy Ritger 
671739a20eSAndy Ritger // Allocate memory of the given type and size in the GPU's UVM internal address
681739a20eSAndy Ritger // space, and (in SR-IOV heavy) map it on the proxy address space as well.
691739a20eSAndy Ritger //
701739a20eSAndy Ritger // The GPU cannot be NULL and the memory is going to mapped on the GPU for the
711739a20eSAndy Ritger // lifetime of the allocation. For sysmem allocations other GPUs can have a
721739a20eSAndy Ritger // mapping created and removed dynamically with the uvm_rm_mem_(un)map_gpu()
731739a20eSAndy Ritger // functions.
741739a20eSAndy Ritger //
7590eb1077SAndy Ritger // Alignment affects only the GPU VA mapping. If gpu_alignment is 0, then 4K
7690eb1077SAndy Ritger // alignment is enforced.
7790eb1077SAndy Ritger //
781739a20eSAndy Ritger // Locking:
791739a20eSAndy Ritger //  - Internally acquires:
801739a20eSAndy Ritger //    - RM API lock
811739a20eSAndy Ritger //    - RM GPUs lock
8290eb1077SAndy Ritger NV_STATUS uvm_rm_mem_alloc(uvm_gpu_t *gpu,
8390eb1077SAndy Ritger                            uvm_rm_mem_type_t type,
8490eb1077SAndy Ritger                            NvLength size,
8590eb1077SAndy Ritger                            NvU64 gpu_alignment,
8690eb1077SAndy Ritger                            uvm_rm_mem_t **rm_mem_out);
871739a20eSAndy Ritger 
881739a20eSAndy Ritger // Free the memory.
891739a20eSAndy Ritger // Clear all mappings and free the memory
901739a20eSAndy Ritger //
911739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
921739a20eSAndy Ritger void uvm_rm_mem_free(uvm_rm_mem_t *rm_mem);
931739a20eSAndy Ritger 
941739a20eSAndy Ritger // Map/Unmap on the CPU
951739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
961739a20eSAndy Ritger NV_STATUS uvm_rm_mem_map_cpu(uvm_rm_mem_t *rm_mem);
971739a20eSAndy Ritger void uvm_rm_mem_unmap_cpu(uvm_rm_mem_t *rm_mem);
981739a20eSAndy Ritger 
991739a20eSAndy Ritger // Shortcut for uvm_rm_mem_alloc() + uvm_rm_mem_map_cpu().
10090eb1077SAndy Ritger // The function fails and nothing is allocated if any of the intermediate steps
10190eb1077SAndy Ritger // fail.
1021739a20eSAndy Ritger //
1031739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
10490eb1077SAndy Ritger NV_STATUS uvm_rm_mem_alloc_and_map_cpu(uvm_gpu_t *gpu,
10590eb1077SAndy Ritger                                        uvm_rm_mem_type_t type,
10690eb1077SAndy Ritger                                        NvLength size,
10790eb1077SAndy Ritger                                        NvU64 gpu_alignment,
10890eb1077SAndy Ritger                                        uvm_rm_mem_t **rm_mem_out);
1091739a20eSAndy Ritger 
1101739a20eSAndy Ritger // Shortcut for uvm_rm_mem_alloc_and_map_cpu() + uvm_rm_mem_map_all_gpus()
11190eb1077SAndy Ritger // The function fails and nothing is allocated if any of the intermediate steps
11290eb1077SAndy Ritger // fail.
1131739a20eSAndy Ritger //
1141739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
11590eb1077SAndy Ritger NV_STATUS uvm_rm_mem_alloc_and_map_all(uvm_gpu_t *gpu,
11690eb1077SAndy Ritger                                        uvm_rm_mem_type_t type,
11790eb1077SAndy Ritger                                        NvLength size,
11890eb1077SAndy Ritger                                        NvU64 gpu_alignment,
11990eb1077SAndy Ritger                                        uvm_rm_mem_t **rm_mem_out);
1201739a20eSAndy Ritger 
1211739a20eSAndy Ritger // Map/Unmap on UVM's internal address space of a GPU. In SR-IOV heavy the
1221739a20eSAndy Ritger // operation is also applied on the GPU's proxy address space.
1231739a20eSAndy Ritger //
1244397463eSAndy Ritger // Mapping/unmapping on the GPU owner, or mapping on an already mapped GPU, are
1254397463eSAndy Ritger // no-ops. Mapping/unmapping on a GPU different from the owner is only supported
1264397463eSAndy Ritger // for system memory.
1271739a20eSAndy Ritger //
1281739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
12990eb1077SAndy Ritger NV_STATUS uvm_rm_mem_map_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu, NvU64 gpu_alignment);
1301739a20eSAndy Ritger void uvm_rm_mem_unmap_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
1311739a20eSAndy Ritger 
1321739a20eSAndy Ritger // Map on UVM's internal address space of all GPUs retained by the UVM driver
1331739a20eSAndy Ritger // that do not yet have this allocation mapped. In SR-IOV heavy the memory is
1341739a20eSAndy Ritger // also mapped on the proxy address space of all GPUs.
1351739a20eSAndy Ritger //
1361739a20eSAndy Ritger // Locking same as uvm_rm_mem_alloc()
13790eb1077SAndy Ritger NV_STATUS uvm_rm_mem_map_all_gpus(uvm_rm_mem_t *rm_mem, NvU64 gpu_alignment);
1381739a20eSAndy Ritger 
1391739a20eSAndy Ritger // Get the CPU VA, GPU VA (UVM internal/kernel address space), or GPU (proxy
1401739a20eSAndy Ritger // address space)
1411739a20eSAndy Ritger void *uvm_rm_mem_get_cpu_va(uvm_rm_mem_t *rm_mem);
1421739a20eSAndy Ritger NvU64 uvm_rm_mem_get_gpu_uvm_va(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
1431739a20eSAndy Ritger NvU64 uvm_rm_mem_get_gpu_proxy_va(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
1441739a20eSAndy Ritger 
1451739a20eSAndy Ritger // Get the GPU VA of the given memory in UVM's internal address space (if the
1461739a20eSAndy Ritger // flag is false), or proxy address space (if flag is true).
147eb5c7665SAndy Ritger 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);
1481739a20eSAndy Ritger 
1491739a20eSAndy Ritger // Query if the memory is mapped on the CPU, GPU (UVM internal/kernel address
1501739a20eSAndy Ritger // space), or GPU (proxy address space)
1511739a20eSAndy Ritger bool uvm_rm_mem_mapped_on_cpu(uvm_rm_mem_t *rm_mem);
1521739a20eSAndy Ritger bool uvm_rm_mem_mapped_on_gpu(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
1531739a20eSAndy Ritger bool uvm_rm_mem_mapped_on_gpu_proxy(uvm_rm_mem_t *rm_mem, uvm_gpu_t *gpu);
1541739a20eSAndy Ritger 
1551739a20eSAndy Ritger #endif // __UVM_RM_MEM_H__
156