gpu: nvgpu: MM SWUD

Add a SWUD (SW Unit Design document) for MM as well as some glue in
the gk20a.h header for a nvgpu wide main-page.

JIRA NVGPU-3544

Change-Id: I7d6ee6ef94d7f0d2c10c0f4d8c860a20b33f7aae
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2129852
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Alex Waterman
2019-05-20 08:02:52 -07:00
committed by mobile promotions
parent 2ba44f30c7
commit 893f28f775
5 changed files with 351 additions and 155 deletions

View File

@@ -23,6 +23,12 @@
#ifndef NVGPU_DMA_H #ifndef NVGPU_DMA_H
#define NVGPU_DMA_H #define NVGPU_DMA_H
/**
* @file
*
* Abstract DMA implementation in nvgpu.
*/
#include <nvgpu/types.h> #include <nvgpu/types.h>
#if defined(__NVGPU_POSIX__) #if defined(__NVGPU_POSIX__)
@@ -37,18 +43,18 @@ struct nvgpu_mem;
* Flags for the below nvgpu_dma_{alloc,alloc_map}_flags* * Flags for the below nvgpu_dma_{alloc,alloc_map}_flags*
*/ */
/* /**
* Don't create a virtual kernel mapping for the buffer but only allocate it; * Don't create a virtual kernel mapping for the buffer but only allocate it;
* this may save some resources. The buffer can be mapped later explicitly. * this may save some resources. The buffer can be mapped later explicitly.
*/ */
#define NVGPU_DMA_NO_KERNEL_MAPPING BIT64(0) #define NVGPU_DMA_NO_KERNEL_MAPPING BIT64(0)
/* /**
* Make the mapping read-only. * Make the mapping read-only.
*/ */
#define NVGPU_DMA_READ_ONLY BIT64(1) #define NVGPU_DMA_READ_ONLY BIT64(1)
/* /**
* Buffer is physically addressed from the GPU. * Buffer is physically addressed from the GPU.
* If device is not iommuable, or nvlink is enabled, don't allow building * If device is not iommuable, or nvlink is enabled, don't allow building
* the buffer from individual pages, but require a physically contiguous * the buffer from individual pages, but require a physically contiguous
@@ -60,7 +66,7 @@ struct nvgpu_mem;
/** /**
* nvgpu_iommuable - Check if GPU is behind IOMMU * nvgpu_iommuable - Check if GPU is behind IOMMU
* *
* @g - The GPU. * @param g - The GPU.
* *
* Returns true if the passed GPU is behind an IOMMU; false otherwise. If the * Returns true if the passed GPU is behind an IOMMU; false otherwise. If the
* GPU is iommuable then the DMA address in nvgpu_mem_sgl is valid. * GPU is iommuable then the DMA address in nvgpu_mem_sgl is valid.
@@ -74,11 +80,11 @@ bool nvgpu_iommuable(struct gk20a *g);
/** /**
* nvgpu_dma_alloc - Allocate DMA memory * nvgpu_dma_alloc - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* memory can be either placed in VIDMEM or SYSMEM, which ever is more * memory can be either placed in VIDMEM or SYSMEM, which ever is more
* convenient for the driver. * convenient for the driver.
@@ -88,12 +94,12 @@ int nvgpu_dma_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
/** /**
* nvgpu_dma_alloc_flags - Allocate DMA memory * nvgpu_dma_alloc_flags - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* memory can be either placed in VIDMEM or SYSMEM, which ever is more * memory can be either placed in VIDMEM or SYSMEM, which ever is more
* convenient for the driver. * convenient for the driver.
@@ -109,11 +115,11 @@ int nvgpu_dma_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
/** /**
* nvgpu_dma_alloc_sys - Allocate DMA memory * nvgpu_dma_alloc_sys - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in SYSMEM. * allocates memory specifically in SYSMEM.
*/ */
@@ -122,12 +128,12 @@ int nvgpu_dma_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
/** /**
* nvgpu_dma_alloc_flags_sys - Allocate DMA memory * nvgpu_dma_alloc_flags_sys - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in SYSMEM. * allocates memory specifically in SYSMEM.
* *
@@ -142,11 +148,11 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
/** /**
* nvgpu_dma_alloc_vid - Allocate DMA memory * nvgpu_dma_alloc_vid - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in VIDMEM. * allocates memory specifically in VIDMEM.
*/ */
@@ -155,12 +161,12 @@ int nvgpu_dma_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
/** /**
* nvgpu_dma_alloc_flags_vid - Allocate DMA memory * nvgpu_dma_alloc_flags_vid - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in VIDMEM. * allocates memory specifically in VIDMEM.
* *
@@ -176,13 +182,13 @@ int nvgpu_dma_alloc_flags_vid(struct gk20a *g, unsigned long flags,
/** /**
* nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory * nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* @at - A specific location to attempt to allocate memory from or 0 if the * @param at - A specific location to attempt to allocate memory from or 0 if
* caller does not care what the address is. * the caller does not care what the address is.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in VIDMEM. * allocates memory specifically in VIDMEM.
* *
@@ -193,14 +199,14 @@ int nvgpu_dma_alloc_vid_at(struct gk20a *g,
/** /**
* nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory * nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory
* *
* @g - The GPU. * @param g - The GPU.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* @at - A specific location to attempt to allocate memory from or 0 if the * @param at - A specific location to attempt to allocate memory from or 0 if
* caller does not care what the address is. * the caller does not care what the address is.
* *
* Allocate memory suitable for doing DMA. Store the allocation info in @mem. * Allocate memory suitable for doing DMA. Store the allocation info in #mem.
* Returns 0 on success and a suitable error code when there's an error. This * Returns 0 on success and a suitable error code when there's an error. This
* allocates memory specifically in VIDMEM. * allocates memory specifically in VIDMEM.
* *
@@ -214,8 +220,8 @@ int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
/** /**
* nvgpu_dma_free - Free a DMA allocation * nvgpu_dma_free - Free a DMA allocation
* *
* @g - The GPU. * @param g - The GPU.
* @mem - An allocation to free. * @param mem - An allocation to free.
* *
* Free memory created with any of: * Free memory created with any of:
* *
@@ -232,9 +238,9 @@ void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem);
/** /**
* nvgpu_dma_alloc_map - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* Note this is different than mapping it into the CPU. This memory can be * Note this is different than mapping it into the CPU. This memory can be
@@ -252,17 +258,17 @@ int nvgpu_dma_alloc_map(struct vm_gk20a *vm, size_t size,
/** /**
* nvgpu_dma_alloc_map_flags - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map_flags - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* Note this is different than mapping it into the CPU. This memory can be * Note this is different than mapping it into the CPU. This memory can be
* either placed in VIDMEM or SYSMEM, which ever is more convenient for the * either placed in VIDMEM or SYSMEM, which ever is more convenient for the
* driver. * driver.
* *
* This version passes @flags on to the underlying DMA allocation. The accepted * This version passes #flags on to the underlying DMA allocation. The accepted
* flags are: * flags are:
* *
* %NVGPU_DMA_NO_KERNEL_MAPPING * %NVGPU_DMA_NO_KERNEL_MAPPING
@@ -274,9 +280,9 @@ int nvgpu_dma_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags,
/** /**
* nvgpu_dma_alloc_map_sys - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map_sys - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* This memory will be placed in SYSMEM. * This memory will be placed in SYSMEM.
@@ -287,15 +293,15 @@ int nvgpu_dma_alloc_map_sys(struct vm_gk20a *vm, size_t size,
/** /**
* nvgpu_dma_alloc_map_flags_sys - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map_flags_sys - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* This memory will be placed in SYSMEM. * This memory will be placed in SYSMEM.
* *
* This version passes @flags on to the underlying DMA allocation. The accepted * This version passes #flags on to the underlying DMA allocation. The accepted
* flags are: * flags are:
* *
* %NVGPU_DMA_NO_KERNEL_MAPPING * %NVGPU_DMA_NO_KERNEL_MAPPING
@@ -307,9 +313,9 @@ int nvgpu_dma_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
/** /**
* nvgpu_dma_alloc_map_vid - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map_vid - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* This memory will be placed in VIDMEM. * This memory will be placed in VIDMEM.
@@ -320,15 +326,15 @@ int nvgpu_dma_alloc_map_vid(struct vm_gk20a *vm, size_t size,
/** /**
* nvgpu_dma_alloc_map_flags_vid - Allocate DMA memory and map into GMMU. * nvgpu_dma_alloc_map_flags_vid - Allocate DMA memory and map into GMMU.
* *
* @vm - VM context for GMMU mapping. * @param vm - VM context for GMMU mapping.
* @flags - Flags modifying the operation of the DMA allocation. * @param flags - Flags modifying the operation of the DMA allocation.
* @size - Size of the allocation in bytes. * @param size - Size of the allocation in bytes.
* @mem - Struct for storing the allocation information. * @param mem - Struct for storing the allocation information.
* *
* Allocate memory suitable for doing DMA and map that memory into the GMMU. * Allocate memory suitable for doing DMA and map that memory into the GMMU.
* This memory will be placed in VIDMEM. * This memory will be placed in VIDMEM.
* *
* This version passes @flags on to the underlying DMA allocation. The accepted * This version passes #flags on to the underlying DMA allocation. The accepted
* flags are: * flags are:
* *
* %NVGPU_DMA_NO_KERNEL_MAPPING * %NVGPU_DMA_NO_KERNEL_MAPPING
@@ -340,8 +346,8 @@ int nvgpu_dma_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
/** /**
* nvgpu_dma_unmap_free - Free a DMA allocation * nvgpu_dma_unmap_free - Free a DMA allocation
* *
* @g - The GPU. * @param g - The GPU.
* @mem - An allocation to free. * @param mem - An allocation to free.
* *
* Free memory created with any of: * Free memory created with any of:
* *

View File

@@ -24,6 +24,24 @@
#ifndef GK20A_H #ifndef GK20A_H
#define GK20A_H #define GK20A_H
/**
* @mainpage
*
* NVGPU Design Documentation
* ==========================
*
* Welcome to the nvgpu unit design documentation. The following pages document
* the major top level units within nvgpu-common:
*
* - @ref unit-mm
* - Etc, etc.
*
* nvgpu-driver Level Requirements Table
* =====================================
*
* ...
*/
struct gk20a; struct gk20a;
struct nvgpu_fifo; struct nvgpu_fifo;
struct nvgpu_channel; struct nvgpu_channel;

View File

@@ -23,6 +23,12 @@
#ifndef NVGPU_KMEM_H #ifndef NVGPU_KMEM_H
#define NVGPU_KMEM_H #define NVGPU_KMEM_H
/**
* @file
*
* Abstract interface for interacting with general kernel memory.
*/
#include <nvgpu/types.h> #include <nvgpu/types.h>
#include <nvgpu/utils.h> #include <nvgpu/utils.h>
@@ -39,7 +45,10 @@ struct gk20a;
#endif #endif
/** /**
* DOC: Kmem cache support * @file
*
* Kmem cache support
* ------------------
* *
* In Linux there is support for the notion of a kmem_cache. It gives better * In Linux there is support for the notion of a kmem_cache. It gives better
* memory usage characteristics for lots of allocations of the same size. Think * memory usage characteristics for lots of allocations of the same size. Think
@@ -70,11 +79,11 @@ struct nvgpu_mem_alloc_tracker;
/** /**
* nvgpu_kmem_cache_create - create an nvgpu kernel memory cache. * nvgpu_kmem_cache_create - create an nvgpu kernel memory cache.
* *
* @g The GPU driver struct using this cache. * @param g The GPU driver struct using this cache.
* @size Size of the object allocated by the cache. * @param size Size of the object allocated by the cache.
* *
* This cache can be used to allocate objects of size @size. Common usage would * This cache can be used to allocate objects of size #size. Common usage would
* be for a struct that gets allocated a lot. In that case @size should be * be for a struct that gets allocated a lot. In that case #size should be
* sizeof(struct my_struct). * sizeof(struct my_struct).
* *
* A given implementation of this need not do anything special. The allocation * A given implementation of this need not do anything special. The allocation
@@ -87,30 +96,30 @@ struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size);
* nvgpu_kmem_cache_destroy - destroy a cache created by * nvgpu_kmem_cache_destroy - destroy a cache created by
* nvgpu_kmem_cache_create(). * nvgpu_kmem_cache_create().
* *
* @cache The cache to destroy. * @param cache The cache to destroy.
*/ */
void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache); void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache);
/** /**
* nvgpu_kmem_cache_alloc - Allocate an object from the cache * nvgpu_kmem_cache_alloc - Allocate an object from the cache
* *
* @cache The cache to alloc from. * @param cache The cache to alloc from.
*/ */
void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache); void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache);
/** /**
* nvgpu_kmem_cache_free - Free an object back to a cache * nvgpu_kmem_cache_free - Free an object back to a cache
* *
* @cache The cache to return the object to. * @param cache The cache to return the object to.
* @ptr Pointer to the object to free. * @param ptr Pointer to the object to free.
*/ */
void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr); void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_kmalloc - Allocate from the kernel's allocator. * nvgpu_kmalloc - Allocate from the kernel's allocator.
* *
* @g: Current GPU. * @param g Current GPU.
* @size: Size of the allocation. * @param size Size of the allocation.
* *
* Allocate a chunk of system memory from the kernel. Allocations larger than 1 * Allocate a chunk of system memory from the kernel. Allocations larger than 1
* page may fail even when there may appear to be enough memory. * page may fail even when there may appear to be enough memory.
@@ -122,8 +131,8 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_kzalloc - Allocate from the kernel's allocator. * nvgpu_kzalloc - Allocate from the kernel's allocator.
* *
* @g: Current GPU. * @param g Current GPU.
* @size: Size of the allocation. * @param size Size of the allocation.
* *
* Identical to nvgpu_kalloc() except the memory will be zeroed before being * Identical to nvgpu_kalloc() except the memory will be zeroed before being
* returned. * returned.
@@ -133,12 +142,12 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_kcalloc - Allocate from the kernel's allocator. * nvgpu_kcalloc - Allocate from the kernel's allocator.
* *
* @g: Current GPU. * @param g Current GPU.
* @n: Number of objects. * @param n Number of objects.
* @size: Size of each object. * @param size Size of each object.
* *
* Identical to nvgpu_kalloc() except the size of the memory chunk returned is * Identical to nvgpu_kalloc() except the size of the memory chunk returned is
* @n * @size. * #n * #size.
*/ */
#define nvgpu_kcalloc(g, n, size) \ #define nvgpu_kcalloc(g, n, size) \
nvgpu_kcalloc_impl(g, n, size, NVGPU_GET_IP) nvgpu_kcalloc_impl(g, n, size, NVGPU_GET_IP)
@@ -146,8 +155,8 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_vmalloc - Allocate memory and return a map to it. * nvgpu_vmalloc - Allocate memory and return a map to it.
* *
* @g: Current GPU. * @param g Current GPU.
* @size: Size of the allocation. * @param size Size of the allocation.
* *
* Allocate some memory and return a pointer to a virtual memory mapping of * Allocate some memory and return a pointer to a virtual memory mapping of
* that memory in the kernel's virtual address space. The underlying physical * that memory in the kernel's virtual address space. The underlying physical
@@ -162,8 +171,8 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_vzalloc - Allocate memory and return a map to it. * nvgpu_vzalloc - Allocate memory and return a map to it.
* *
* @g: Current GPU. * @param g Current GPU.
* @size: Size of the allocation. * @param size Size of the allocation.
* *
* Identical to nvgpu_vmalloc() except this will return zero'ed memory. * Identical to nvgpu_vmalloc() except this will return zero'ed memory.
*/ */
@@ -173,16 +182,16 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
* nvgpu_kfree - Frees an alloc from nvgpu_kmalloc, nvgpu_kzalloc, * nvgpu_kfree - Frees an alloc from nvgpu_kmalloc, nvgpu_kzalloc,
* nvgpu_kcalloc. * nvgpu_kcalloc.
* *
* @g: Current GPU. * @param g Current GPU.
* @addr: Address of object to free. * @param addr Address of object to free.
*/ */
#define nvgpu_kfree(g, addr) nvgpu_kfree_impl(g, addr) #define nvgpu_kfree(g, addr) nvgpu_kfree_impl(g, addr)
/** /**
* nvgpu_vfree - Frees an alloc from nvgpu_vmalloc, nvgpu_vzalloc. * nvgpu_vfree - Frees an alloc from nvgpu_vmalloc, nvgpu_vzalloc.
* *
* @g: Current GPU. * @param g Current GPU.
* @addr: Address of object to free. * @param addr Address of object to free.
*/ */
#define nvgpu_vfree(g, addr) nvgpu_vfree_impl(g, addr) #define nvgpu_vfree(g, addr) nvgpu_vfree_impl(g, addr)
@@ -192,7 +201,7 @@ void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
/** /**
* nvgpu_kmem_init - Initialize the kmem tracking stuff. * nvgpu_kmem_init - Initialize the kmem tracking stuff.
* *
*@g: The driver to init. * @param g The driver to init.
* *
* Returns non-zero on failure. * Returns non-zero on failure.
*/ */
@@ -201,19 +210,19 @@ int nvgpu_kmem_init(struct gk20a *g);
/** /**
* nvgpu_kmem_fini - Finalize the kmem tracking code * nvgpu_kmem_fini - Finalize the kmem tracking code
* *
* @g - The GPU. * @param g The GPU.
* @flags - Flags that control operation of this finalization. * @param flags Flags that control operation of this finalization.
* *
* Cleanup resources used by nvgpu_kmem. Available flags for cleanup are: * Cleanup resources used by nvgpu_kmem. Available flags for cleanup are:
* *
* %NVGPU_KMEM_FINI_DO_NOTHING * - NVGPU_KMEM_FINI_DO_NOTHING
* %NVGPU_KMEM_FINI_FORCE_CLEANUP * - NVGPU_KMEM_FINI_FORCE_CLEANUP
* %NVGPU_KMEM_FINI_DUMP_ALLOCS * - NVGPU_KMEM_FINI_DUMP_ALLOCS
* %NVGPU_KMEM_FINI_WARN * - NVGPU_KMEM_FINI_WARN
* %NVGPU_KMEM_FINI_BUG * - NVGPU_KMEM_FINI_BUG
* *
* %NVGPU_KMEM_FINI_DO_NOTHING will be overridden by anything else specified. * NVGPU_KMEM_FINI_DO_NOTHING will be overridden by anything else specified.
* Put another way don't just add %NVGPU_KMEM_FINI_DO_NOTHING and expect that * Put another way don't just add NVGPU_KMEM_FINI_DO_NOTHING and expect that
* to suppress other flags from doing anything. * to suppress other flags from doing anything.
*/ */
void nvgpu_kmem_fini(struct gk20a *g, int flags); void nvgpu_kmem_fini(struct gk20a *g, int flags);
@@ -235,8 +244,8 @@ void *nvgpu_big_alloc_impl(struct gk20a *g, size_t size, bool clear);
/** /**
* nvgpu_big_malloc - Pick virtual or physical alloc based on @size * nvgpu_big_malloc - Pick virtual or physical alloc based on @size
* *
* @g - The GPU. * @param g The GPU.
* @size - Size of the allocation. * @param size Size of the allocation.
* *
* On some platforms (i.e Linux) it is possible to allocate memory directly * On some platforms (i.e Linux) it is possible to allocate memory directly
* mapped into the kernel's address space (kmalloc) or allocate discontiguous * mapped into the kernel's address space (kmalloc) or allocate discontiguous
@@ -262,8 +271,8 @@ static inline void *nvgpu_big_malloc(struct gk20a *g, size_t size)
/** /**
* nvgpu_big_malloc - Pick virtual or physical alloc based on @size * nvgpu_big_malloc - Pick virtual or physical alloc based on @size
* *
* @g - The GPU. * @param g The GPU.
* @size - Size of the allocation. * @param size Size of the allocation.
* *
* Zeroed memory version of nvgpu_big_malloc(). * Zeroed memory version of nvgpu_big_malloc().
*/ */
@@ -275,8 +284,8 @@ static inline void *nvgpu_big_zalloc(struct gk20a *g, size_t size)
/** /**
* nvgpu_big_free - Free and alloc from nvgpu_big_zalloc() or * nvgpu_big_free - Free and alloc from nvgpu_big_zalloc() or
* nvgpu_big_malloc(). * nvgpu_big_malloc().
* @g - The GPU. * @param g The GPU.
* @p - A pointer allocated by nvgpu_big_zalloc() or nvgpu_big_malloc(). * @param p A pointer allocated by nvgpu_big_zalloc() or nvgpu_big_malloc().
*/ */
void nvgpu_big_free(struct gk20a *g, void *p); void nvgpu_big_free(struct gk20a *g, void *p);

View File

@@ -23,6 +23,148 @@
#ifndef NVGPU_MM_H #ifndef NVGPU_MM_H
#define NVGPU_MM_H #define NVGPU_MM_H
/**
* @file
* @page unit-mm Unit MM
*
* Overview
* ========
*
* The MM unit is responsible for managing memory in nvgpu. Memory consists
* primarily of two types:
*
* + Regular kernel memory
* + Device accessible memory (DMA memory)
*
* The MM code also makes sure that all of the necessary SW and HW
* initialization for any memory subsystems are taken care of before the GPU
* begins executing work.
*
* Regular Kernel Memory
* ---------------------
*
* The MM unit generally relies on the underlying system to manage kernel
* memory. The nvgpu_kmalloc() and friends implementation is handled by
* kmalloc() on Linux for example.
*
* See include/nvgpu/kmem.h for more details.
*
* DMA
* ---
*
* DMA memory is more complex since it depends on both the GPU hardware and the
* underlying operating system to handle mapping of DMA memory into the GMMU
* (GPU Memory Management Unit). See the following documents for a reference
* describing DMA support in nvgpu-driver:
*
* + include/nvgpu/dma.h
* + include/nvgpu/vm.h
* + include/nvgpu/gmmu.h
* + include/nvgpu/nvgpu_mem.h
* + include/nvgpu/nvgpu_sgt.h
*
* Data Structures
* ===============
*
* The major data structures exposed to users of the MM unit in nvgpu all relate
* to managing DMA buffers and mapping DMA buffers into a GMMU context. The
* following is a list of these structures:
*
* + struct mm_gk20a
*
* struct mm_gk20a defines a single GPU's memory context. It contains
* descriptions of various system GMMU contexts and other GPU global
* locks, descriptions, etc.
*
* + struct vm_gk20a
*
* struct vm_gk20a describes a single GMMU context. This is made up of a
* page directory base (PDB) and other meta data necessary for managing
* GPU memory mappings within this context.
*
* + struct nvgpu_mem
*
* struct nvgpu_mem abstracts all forms of GPU accessible memory which may
* or may not be backed by an SGT/SGL. This structure forms the basis for
* all GPU accessible memory within nvgpu-common.
*
* + struct nvgpu_sgt
*
* In most modern operating systems a DMA buffer may actually be comprised
* of many smaller buffers. This is because in a system running for
* extended periods of time the memory starts to become fragmented at page
* level granularity. Thus when trying to allocate a buffer larger than a
* page it's possible that there won't be a large enough contiguous region
* capable of satisfying the allocation despite there apparently being
* more than enough available space.
*
* This classic fragmentation problem is solved by using lists or tables
* of sub-allocations, that together, form a single DMA buffer. To manage
* these buffers the notion of a scatter-gather list or scatter gather
* table (SGL and SGT, respectively) are introduced.
*
* + struct nvgpu_mapped_buf
*
* This describes a mapping of a userspace provided buffer.
*
* Static Design
* =============
*
* Details of static design.
*
* Resource utilization
* --------------------
*
* External APIs
* -------------
*
* + nvgpu_mm_setup_hw()
*
*
* Supporting Functionality
* ========================
*
* There's a fair amount of supporting functionality:
*
* + Allocators
* - Buddy allocator
* - Page allocator
* - Bitmap allocator
* + vm_area
* + gmmu
* # pd_cache
* # page_table
*
* Documentation for this will be filled in!
*
* Dependencies
* ------------
*
* Dynamic Design
* ==============
*
* Use case descriptions go here. Some potentials:
*
* - nvgpu_vm_map()
* - nvgpu_gmmu_map()
* - nvgpu_dma_alloc()
*
* Requirements
* ============
*
* I added this section to link to unit level requirements. Seems like it's
* missing from the IPP template.
*
* Requirement | Link
* ----------- | ---------------------------------------------------------------------------
* NVGPU-RQCD-45 | https://nvidia.jamacloud.com/perspective.req#/items/6434840?projectId=20460
*
* Open Items
* ==========
*
* Any open items can go here.
*/
#include <nvgpu/vm.h> #include <nvgpu/vm.h>
#include <nvgpu/types.h> #include <nvgpu/types.h>
#include <nvgpu/cond.h> #include <nvgpu/cond.h>
@@ -48,6 +190,12 @@ enum nvgpu_flush_op {
NVGPU_FLUSH_CBC_CLEAN, NVGPU_FLUSH_CBC_CLEAN,
}; };
/**
* This struct keeps track of a given GPU's memory management state. Each GPU
* has exactly one of these structs embedded directly in the gk20a struct. Some
* memory state is tracked on a per-context basis in the <nvgpu/vm.h> header but
* for state that's global to a given GPU this is used.
*/
struct mm_gk20a { struct mm_gk20a {
struct gk20a *g; struct gk20a *g;
@@ -192,6 +340,11 @@ int nvgpu_mm_suspend(struct gk20a *g);
u32 nvgpu_mm_get_default_big_page_size(struct gk20a *g); u32 nvgpu_mm_get_default_big_page_size(struct gk20a *g);
u32 nvgpu_mm_get_available_big_page_sizes(struct gk20a *g); u32 nvgpu_mm_get_available_big_page_sizes(struct gk20a *g);
/**
* Setup MM.
*
* @param g - The GPU.
*/
int nvgpu_mm_setup_hw(struct gk20a *g); int nvgpu_mm_setup_hw(struct gk20a *g);
#endif /* NVGPU_MM_H */ #endif /* NVGPU_MM_H */

View File

@@ -20,6 +20,50 @@
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*/ */
/**
* @file
*
* This header contains the OS agnostic APIs for dealing with VMs. Most of the
* VM implementation is system specific - it must translate from a platform's
* representation of DMA'able memory to our nvgpu_mem notion.
*
* However, some stuff is platform agnostic. VM ref-counting and the VM struct
* itself are platform agnostic. Also, the initialization and destruction of
* VMs is the same across all platforms (for now).
*
* VM Design:
* ----------------
*
* The VM managment in nvgpu is split up as follows: a vm_gk20a struct which
* defines an address space. Each address space is a set of page tables and a
* GPU Virtual Address (GVA) allocator. Any number of channels may bind to a VM.
*
* +----+ +----+ +----+ +-----+ +-----+
* | C1 | | C2 | ... | Cn | | VM1 | ... | VMn |
* +-+--+ +-+--+ +-+--+ +--+--+ +--+--+
* | | | | |
* | | +----->-----+ |
* | +---------------->-----+ |
* +------------------------>-----------------+
*
* Each VM also manages a set of mapped buffers (struct nvgpu_mapped_buf)
* which corresponds to _user space_ buffers which have been mapped into this VM.
* Kernel space mappings (created by nvgpu_gmmu_map()) are not tracked by VMs.
* This may be an architectural bug, but for now it seems to be OK. VMs can be
* closed in various ways - refs counts hitting zero, direct calls to the remove
* routine, etc. Note: this is going to change. VM cleanup is going to be
* homogonized around ref-counts. When a VM is closed all mapped buffers in the
* VM are unmapped from the GMMU. This means that those mappings will no longer
* be valid and any subsequent access by the GPU will fault. That means one must
* ensure the VM is not in use before closing it.
*
* VMs may also contain VM areas (struct nvgpu_vm_area) which are created for
* the purpose of sparse and/or fixed mappings. If userspace wishes to create a
* fixed mapping it must first create a VM area - either with a fixed address or
* not. VM areas are reserved - other mapping operations will not use the space.
* Userspace may then create fixed mappings within that VM area.
*/
#ifndef NVGPU_VM_H #ifndef NVGPU_VM_H
#define NVGPU_VM_H #define NVGPU_VM_H
@@ -53,48 +97,6 @@ struct nvgpu_os_buffer;
#include <nvgpu_rmos/include/vm.h> #include <nvgpu_rmos/include/vm.h>
#endif #endif
/**
* This header contains the OS agnostic APIs for dealing with VMs. Most of the
* VM implementation is system specific - it must translate from a platform's
* representation of DMA'able memory to our nvgpu_mem notion.
*
* However, some stuff is platform agnostic. VM ref-counting and the VM struct
* itself are platform agnostic. Also, the initialization and destruction of
* VMs is the same across all platforms (for now).
*
* VM Architecture:
* ----------------
*
* The VM managment in nvgpu is split up as follows: a vm_gk20a struct which
* defines an address space. Each address space is a set of page tables and a
* GPU Virtual Address (GVA) allocator. Any number of channels may bind to a VM.
*
* +----+ +----+ +----+ +-----+ +-----+
* | C1 | | C2 | ... | Cn | | VM1 | ... | VMn |
* +-+--+ +-+--+ +-+--+ +--+--+ +--+--+
* | | | | |
* | | +----->-----+ |
* | +---------------->-----+ |
* +------------------------>-----------------+
*
* Each VM also manages a set of mapped buffers (struct nvgpu_mapped_buf)
* which corresponds to _user space_ buffers which have been mapped into this VM.
* Kernel space mappings (created by nvgpu_gmmu_map()) are not tracked by VMs.
* This may be an architectural bug, but for now it seems to be OK. VMs can be
* closed in various ways - refs counts hitting zero, direct calls to the remove
* routine, etc. Note: this is going to change. VM cleanup is going to be
* homogonized around ref-counts. When a VM is closed all mapped buffers in the
* VM are unmapped from the GMMU. This means that those mappings will no longer
* be valid and any subsequent access by the GPU will fault. That means one must
* ensure the VM is not in use before closing it.
*
* VMs may also contain VM areas (struct nvgpu_vm_area) which are created for
* the purpose of sparse and/or fixed mappings. If userspace wishes to create a
* fixed mapping it must first create a VM area - either with a fixed address or
* not. VM areas are reserved - other mapping operations will not use the space.
* Userspace may then create fixed mappings within that VM area.
*/
/* map/unmap batch state */ /* map/unmap batch state */
struct vm_gk20a_mapping_batch { struct vm_gk20a_mapping_batch {
bool gpu_l2_flushed; bool gpu_l2_flushed;
@@ -143,6 +145,9 @@ mapped_buffer_from_rbtree_node(struct nvgpu_rbtree_node *node)
((uintptr_t)node - offsetof(struct nvgpu_mapped_buf, node)); ((uintptr_t)node - offsetof(struct nvgpu_mapped_buf, node));
} }
/**
* Virtual Memory context.
*/
struct vm_gk20a { struct vm_gk20a {
struct mm_gk20a *mm; struct mm_gk20a *mm;
struct gk20a_as_share *as_share; /* as_share this represents */ struct gk20a_as_share *as_share; /* as_share this represents */
@@ -255,6 +260,11 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm,
u32 flags, u32 flags,
int kind); int kind);
/**
* Map a DMA buffer into the passed VM context.
*
* @g - the GPU.
*/
int nvgpu_vm_map(struct vm_gk20a *vm, int nvgpu_vm_map(struct vm_gk20a *vm,
struct nvgpu_os_buffer *os_buf, struct nvgpu_os_buffer *os_buf,
struct nvgpu_sgt *sgt, struct nvgpu_sgt *sgt,