From 425f0871d285e22e429dec376f5a75acca558f3e Mon Sep 17 00:00:00 2001 From: Vedashree Vidwans Date: Mon, 23 Sep 2019 17:08:17 -0700 Subject: [PATCH] gpu: nvgpu: add doxygen documentation mm.allocator Add doxygen documentation in allocator.h for mm.allocator. Jira NVGPU-4035 Change-Id: I8c586e6d2da52de1246d5584c65773723203d506 Signed-off-by: Vedashree Vidwans Reviewed-on: https://git-master.nvidia.com/r/2204125 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/include/nvgpu/allocator.h | 495 +++++++++++++++++--- 1 file changed, 424 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/nvgpu/include/nvgpu/allocator.h b/drivers/gpu/nvgpu/include/nvgpu/allocator.h index 5bceeac50..8085db3a5 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/allocator.h +++ b/drivers/gpu/nvgpu/include/nvgpu/allocator.h @@ -51,84 +51,222 @@ struct nvgpu_alloc_carveout; struct vm_gk20a; struct gk20a; -/* - * Operations for an allocator to implement. +/** + * Structure containing operations for an allocator to implement. */ struct nvgpu_allocator_ops { + /** + * @brief Interface to allocate memory. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] len Size of allocation. + * + * @return Address of allocation in case of success, 0 otherwise. + */ u64 (*alloc)(struct nvgpu_allocator *allocator, u64 len); + /** + * @brief Interface to allocate specific pte size memory. + * + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] len Size of allocation. + * @param[in] page_size Page size of resource + * + * @return Address of allocation in case of success, 0 otherwise. + */ u64 (*alloc_pte)(struct nvgpu_allocator *allocator, u64 len, u32 page_size); + /** + * @brief Interface to free given address allocation. + * + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] addr Base address of allocation. + */ void (*free_alloc)(struct nvgpu_allocator *allocator, u64 addr); - /* - * Special interface to allocate a memory region with a specific - * starting address. Yikes. Note: if free() works for freeing both - * regular and fixed allocations then free_fixed() does not need to - * be implemented. This behavior exists for legacy reasons and should - * not be propagated to new allocators. + /** + * @brief Interface to allocate a memory region with specific starting + * address. * - * For allocators where the @page_size field is not applicable it can + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] base Start address of resource. + * @param[in] len Size of allocation. + * @param[in] page_size Page size of resource. + * + * For allocators where \a page_size field is not applicable it can * be left as 0. Otherwise a valid page size should be passed (4k or * what the large page size is). + * + * @return Address of allocation in case of success, 0 otherwise. */ u64 (*alloc_fixed)(struct nvgpu_allocator *allocator, u64 base, u64 len, u32 page_size); + /** + * @brief Free fixed allocation with specific base. + * + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] base Start address of resource. + * @param[in] len Size of allocation. + * + * Note: if free_alloc() works for freeing both regular and fixed + * allocations then free_fixed() does not need to be implemented. This + * behavior exists for legacy reasons and should not be propagated to + * new allocators. + */ void (*free_fixed)(struct nvgpu_allocator *allocator, u64 base, u64 len); - /* - * Allow allocators to reserve space for carveouts. + /** + * @brief Interface to allocate memory carveout. + * + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] co Pointer to carveout structure. + * + * @return 0 in case of success, < 0 in case of failure. */ int (*reserve_carveout)(struct nvgpu_allocator *allocator, struct nvgpu_alloc_carveout *co); + /** + * @brief Interface to release memory carveout. + * + * @param allocator Pointer to nvgpu allocator. + * @param co Pointer to carveout structure. + */ void (*release_carveout)(struct nvgpu_allocator *allocator, struct nvgpu_alloc_carveout *co); - /* - * Returns info about the allocator. + /** + * @brief Interface to read base address of allocator. + * + * @param[in] allocator Pointer to nvgpu allocator. + * + * @return Allocator start address. */ u64 (*base)(struct nvgpu_allocator *allocator); + + /** + * @brief Interface to read length of allocator. + * + * @param[in] allocator Pointer to nvgpu allocator. + * + * @return Allocator end address. + */ u64 (*length)(struct nvgpu_allocator *allocator); + + /** + * @brief Interface to read end address of allocator. + * + * @param[in] allocator Pointer to nvgpu allocator. + * + * @return Allocator end address. + */ u64 (*end)(struct nvgpu_allocator *allocator); + + /** + * @brief Interface to check if allocator is initialized. + * + * @param allocator Pointer to nvgpu allocator. + * + * @return True if allocator is initialized, false otherwise. + */ bool (*inited)(struct nvgpu_allocator *allocator); + + /** + * @brief Interface to read available memory space in allocator. + * + * @param[in] allocator Pointer to nvgpu allocator. + * + * @return Available allocator space. + */ u64 (*space)(struct nvgpu_allocator *allocator); - /* Destructor. */ + /** + * @brief Interface to destroy allocator. + * + * @param[in] allocator Pointer to nvgpu allocator. + */ void (*fini)(struct nvgpu_allocator *allocator); #ifdef __KERNEL__ - /* Debugging. */ + /** + * @brief Interface to print allocator details for debugging. + * + * @param[in] allocator Pointer to nvgpu allocator. + * @param[in] s File pointer. If NULL, details are + * printed to kernel log. + * @param[in] lock Lock variable. + */ void (*print_stats)(struct nvgpu_allocator *allocator, struct seq_file *s, int lock); #endif }; +/** + * Basic structure to hold details of an allocator. + */ struct nvgpu_allocator { + /** + * Pointer to GPU structure. + */ struct gk20a *g; - + /** + * Name of allocator. + */ char name[32]; + /** + * Synchronization mutex. + */ struct nvgpu_mutex lock; - + /** + * Generally used to store pointer to specific type of allocator. + */ void *priv; + /** + * Pointer to allocator operations. + */ const struct nvgpu_allocator_ops *ops; - + /** + * Pointer to debugfs node. + */ struct dentry *debugfs_entry; - bool debug; /* Control for debug msgs. */ + /** + * Control for debug msgs. + */ + bool debug; }; +/** + * Basic structure to hold details of allocated carveout. + */ struct nvgpu_alloc_carveout { + /** + * Name of allocated carveout. + */ const char *name; + /** + * Base address of carveout. + */ u64 base; + /** + * Length of carveout. + */ u64 length; - + /** + * Pointer to allocator structure. + */ struct nvgpu_allocator *allocator; - - /* - * For usage by the allocator implementation. + /** + * List node for usage by the allocator implementation. */ struct nvgpu_list_node co_entry; }; +/** + * @brief Get address of carveout structure from given nvgpu list node. + * + * @param[in] node Pointer to nvgpu list node. + * + * @return allocated carveout structure pointer. + */ static inline struct nvgpu_alloc_carveout * nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) { @@ -136,6 +274,13 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) ((uintptr_t)node - offsetof(struct nvgpu_alloc_carveout, co_entry)); }; +/** + * @brief Macro to set carveout attributes. + * + * @param[in] local_name Name of carveout. + * @param[in] local_base Base address of carveout. + * @param[in] local_length Length of carveout. + */ #define NVGPU_CARVEOUT(local_name, local_base, local_length) \ { \ .name = (local_name), \ @@ -143,11 +288,7 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) .length = (local_length) \ } -/* - * These are the available allocator flags. - * - * GPU_ALLOC_GVA_SPACE - * +/** * This flag makes sense for the buddy allocator only. It specifies that the * allocator will be used for managing a GVA space. When managing GVA spaces * special care has to be taken to ensure that allocations of similar PTE @@ -155,9 +296,10 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) * code to skip defining both small and large PTE tables for every PDE. That * can save considerable memory for address spaces that have a lot of * allocations. - * - * GPU_ALLOC_NO_ALLOC_PAGE - * + */ +#define GPU_ALLOC_GVA_SPACE BIT64(0) + +/** * For any allocator that needs to manage a resource in a latency critical * path this flag specifies that the allocator should not use any kmalloc() * or similar functions during normal operation. Initialization routines @@ -170,9 +312,10 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) * allocations you need to keep track of the meta-data yourself (in this * case the base and length of the allocation as opposed to just the base * of the allocation). - * - * GPU_ALLOC_4K_VIDMEM_PAGES - * + */ +#define GPU_ALLOC_NO_ALLOC_PAGE BIT64(1) + +/** * We manage vidmem pages at a large page granularity for performance * reasons; however, this can lead to wasting memory. For page allocators * setting this flag will tell the allocator to manage pools of 4K pages @@ -181,26 +324,25 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) * Currently this flag is ignored since the only usage of the page allocator * uses a 4K block size already. However, this flag has been reserved since * it will be necessary in the future. - * - * GPU_ALLOC_FORCE_CONTIG - * + */ +#define GPU_ALLOC_4K_VIDMEM_PAGES BIT64(2) + +/** * Force allocations to be contiguous. Currently only relevant for page * allocators since all other allocators are naturally contiguous. - * - * GPU_ALLOC_NO_SCATTER_GATHER - * + */ +#define GPU_ALLOC_FORCE_CONTIG BIT64(3) + +/** * The page allocator normally returns a scatter gather data structure for * allocations (to handle discontiguous pages). However, at times that can * be annoying so this flag forces the page allocator to return a u64 * pointing to the allocation base (requires GPU_ALLOC_FORCE_CONTIG to be * set as well). */ -#define GPU_ALLOC_GVA_SPACE BIT64(0) -#define GPU_ALLOC_NO_ALLOC_PAGE BIT64(1) -#define GPU_ALLOC_4K_VIDMEM_PAGES BIT64(2) -#define GPU_ALLOC_FORCE_CONTIG BIT64(3) #define GPU_ALLOC_NO_SCATTER_GATHER BIT64(4) +/** Enumerated type used to identify various allocator types */ enum nvgpu_allocator_type { BUDDY_ALLOCATOR = 0, #ifdef CONFIG_NVGPU_DGPU @@ -209,56 +351,106 @@ enum nvgpu_allocator_type { BITMAP_ALLOCATOR }; +/** + * @brief Acquire mutex associated with allocator. + * + * @param[in] a Pointer to nvgpu allocator. + */ static inline void alloc_lock(struct nvgpu_allocator *a) { nvgpu_mutex_acquire(&a->lock); } +/** + * @brief Release mutex associated with allocator. + * + * @param[in] a Pointer to nvgpu allocator. + */ static inline void alloc_unlock(struct nvgpu_allocator *a) { nvgpu_mutex_release(&a->lock); } -/* - * Buddy allocator specific initializers. +/** + * @brief Initialize buddy allocator. + * + * @param[in] g Pointer to GPU structure. + * @param[in] na Pointer to allocator structure. + * @param[in] vm Pointer to virtual memory. + * @param[in] name Name of buddy allocator. + * @param[in] base Base address of buddy allocator. + * @param[in] size Size of buddy allocator. + * @param[in] blk_size Block size of buddy allocator. + * @param[in] max_order Maximum allowed buddy order. + * @param[in] flags Flags indicating buddy allocator conditions. + * + * @return 0 in case of success, < 0 otherwise. + * @retval -EINVAL in case of incorrect input value. + * @retval -ENOMEM in case there is not enough memory for allocation. */ int nvgpu_buddy_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, struct vm_gk20a *vm, const char *name, u64 base, u64 size, u64 blk_size, u64 max_order, u64 flags); -/* - * Bitmap initializers. +/** + * @brief Initialize bitmap allocator. + * + * @param[in] g Pointer to GPU structure. + * @param[in] na Pointer to allocator structure. + * @param[in] name Name of bitmap allocator. + * @param[in] base Base address of bitmap allocator. + * @param[in] length Size of bitmap allocator. + * @param[in] blk_size Block size of bitmap allocator. + * @param[in] flags Flags indicating bitmap allocator conditions. + * + * @return 0 in case of success, < 0 otherwise. + * @retval -EINVAL in case of incorrect input value. + * @retval -ENOMEM in case there is not enough memory for allocation. */ int nvgpu_bitmap_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, const char *name, u64 base, u64 length, u64 blk_size, u64 flags); #ifdef CONFIG_NVGPU_DGPU -/* - * Page allocator initializers. + +/** + * @brief Initialize page allocator. + * + * @param[in] g Pointer to GPU structure. + * @param[in] na Pointer to allocator structure. + * @param[in] name Name of page allocator. + * @param[in] base Base address of page allocator. + * @param[in] length Size of page allocator. + * @param[in] blk_size Block size of page allocator. + * @param[in] flags Flags indicating page allocator conditions. + * + * @return 0 in case of success, < 0 otherwise. + * @retval -EINVAL in case of incorrect input value. + * @retval -ENOMEM in case there is not enough memory for allocation. */ int nvgpu_page_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, const char *name, u64 base, u64 length, u64 blk_size, u64 flags); #endif -/* - * Common init function for any type of allocator. - * Returns 0 on success. +/** + * @brief Common init function for any type of allocator. * - * @g: GPU pointer - * @na: Pointer to nvgpu_allocator struct - * @vm: VM to be associated with an allocator. Can be NULL. - * Applicable to buddy allocator only. - * @name: Name of the allocator. - * @base: Base address of the allocator. - * @length: Size of the allocator. - * @blk_size: Lowest size of resources that can be allocated. - * @max_order: Max order of resource slices that can be allocated. - * Applicable to buddy allocator only. - * @flags: Additional required flags. - * @alloc_type: Allocator type. + * @param[in] g Pointer to GPU structure. + * @param[in] na Pointer to allocator structure. + * @param[in] vm Pointer to virtual memory. Can be NULL. + * Applicable to buddy allocator only. + * @param[in] name Name of allocator. + * @param[in] base Base address of allocator. + * @param[in] length Size of allocator. + * @param[in] blk_size Lowest size of resources that can be allocated. + * @param[in] max_order Max order of resource slices that can be + * allocated. Applicable to buddy allocator only. + * @param[in] flags Flags indicating additional conditions. + * @param[in] alloc_type Allocator type. + + * Returns 0 in case of success, < 0 otherwise. */ int nvgpu_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, struct vm_gk20a *vm, const char *name, @@ -266,47 +458,174 @@ int nvgpu_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, u64 flags, enum nvgpu_allocator_type alloc_type); #ifdef CONFIG_NVGPU_FENCE -/* - * Lockless allocatior initializers. - * Note: This allocator can only allocate fixed-size structures of a - * pre-defined size. +/** + * @brief Initialize lockless allocator. + * + * @param[in] g Pointer to GPU structure. + * @param[in] na Pointer to allocator structure. + * @param[in] name Name of lockless allocator. + * @param[in] base Base address of lockless allocator. + * @param[in] length Size of lockless allocator. + * @param[in] blk_size Block size of lockless allocator. + * @param[in] flags Flags indicating lockless allocator conditions. + * + * @return 0 in case of success, < 0 otherwise. + * @retval -EINVAL in case of incorrect input value. + * @retval -ENOMEM in case there is not enough memory for allocation. */ int nvgpu_lockless_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, const char *name, u64 base, u64 length, u64 blk_size, u64 flags); #endif +/** + * Largest block of resources that fits in address space. + */ #define GPU_BALLOC_MAX_ORDER 63U -/* - * Allocator APIs. +/** + * @brief Interface to allocate resources. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] len Size of allocation. + * + * @return Address of allocation in case of success, 0 otherwise. */ u64 nvgpu_alloc(struct nvgpu_allocator *a, u64 len); + +/** + * @brief Interface to allocate resources with specific pte. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] len Size of allocation. + * @param[in] page_size Page size of resource. + * + * @return Address of allocation in case of success, 0 otherwise. + */ u64 nvgpu_alloc_pte(struct nvgpu_allocator *a, u64 len, u32 page_size); + +/** + * @brief Interface to free allocated resources. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] addr Base address of allocation. + */ void nvgpu_free(struct nvgpu_allocator *a, u64 addr); +/** + * @brief Interface to allocate resources with specific start address. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] base Start address of resource. + * @param[in] len Size of allocation. + * @param[in] page_size Page size of resource. + * + * @return Address of allocation in case of success, 0 otherwise. + */ u64 nvgpu_alloc_fixed(struct nvgpu_allocator *a, u64 base, u64 len, u32 page_size); + +/** + * @brief Interface to free resources at specific start address. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] base Start address of resource. + * @param[in] len Size of allocation. + */ void nvgpu_free_fixed(struct nvgpu_allocator *a, u64 base, u64 len); +/** + * @brief Interface to reserve carveout. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] co Pointer to carveout structure. + * + * @return 0 in case of success, < 0 in case of failure. + */ int nvgpu_alloc_reserve_carveout(struct nvgpu_allocator *a, struct nvgpu_alloc_carveout *co); + +/** + * @brief Interface to release carveout. + * + * @param a Pointer to nvgpu allocator. + * @param co Pointer to carveout structure. + */ void nvgpu_alloc_release_carveout(struct nvgpu_allocator *a, struct nvgpu_alloc_carveout *co); +/** + * @brief Interface to read allocator base. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return Allocator start address. + */ u64 nvgpu_alloc_base(struct nvgpu_allocator *a); + +/** + * @brief Interface to read allocator length. + * + * @param a Pointer to nvgpu allocator. + * + * @return Allocator length address. + */ u64 nvgpu_alloc_length(struct nvgpu_allocator *a); + +/** + * @brief Interface to read allocator end address. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return Allocator end address. + */ u64 nvgpu_alloc_end(struct nvgpu_allocator *a); + +/** + * @brief Interface to check if allocator is initialized. + * + * @param a Pointer to nvgpu allocator. + * + * @return True if allocator is initialized, false otherwise. + */ bool nvgpu_alloc_initialized(struct nvgpu_allocator *a); + +/** + * @brief Interface to get allocator space. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return Available allocator space. + */ u64 nvgpu_alloc_space(struct nvgpu_allocator *a); +/** + * @brief Interface to destroy allocator. + * + * @param[in] a Pointer to nvgpu allocator. + */ void nvgpu_alloc_destroy(struct nvgpu_allocator *a); #ifdef __KERNEL__ +/** + * @brief Interface to print allocator details. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] s File pointer. + * If NULL, details are printed to kernel log. + * @param[in] lock Lock variable. + */ void nvgpu_alloc_print_stats(struct nvgpu_allocator *a, struct seq_file *s, int lock); #endif +/** + * @brief Get GPU pointer from allocator pointer. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return GPU pointer. + */ static inline struct gk20a *nvgpu_alloc_to_gpu(struct nvgpu_allocator *a) { return a->g; @@ -316,19 +635,53 @@ static inline struct gk20a *nvgpu_alloc_to_gpu(struct nvgpu_allocator *a) /* * Common functionality for the internals of the allocators. */ +/** + * @brief Initialize debug allocator file. + * + * @param[in] g Pointer to GPU structure. + * @param[in] a Pointer to nvgpu allocator. + */ void nvgpu_init_alloc_debug(struct gk20a *g, struct nvgpu_allocator *a); + +/** + * @brief Destroy debug allocator file. + * + * @param[in] a Pointer to nvgpu allocator. + */ void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a); #endif +/** + * @brief Initialize nvgpu allocator. + * + * @param[in] a Pointer to nvgpu allocator. + * @param[in] g Pointer to GPU structure. + * @param[in] name Name of allocator. + * @param[in] priv Pointer to private data. + * @param[in] dbg Debug flag. + * @param[in] ops Pointer to allocator operations. + * + * @return 0 in case of success, < 0 in case of failure. + */ int nvgpu_alloc_common_init(struct nvgpu_allocator *a, struct gk20a *g, const char *name, void *priv, bool dbg, const struct nvgpu_allocator_ops *ops); +/** + * @brief Enable allocator debug. + * + * @param[in] a Pointer to nvgpu allocator. + */ static inline void nvgpu_alloc_enable_dbg(struct nvgpu_allocator *a) { a->debug = true; } +/** + * @brief Disable allocator debug. + * + * @param[in] a Pointer to nvgpu allocator. + */ static inline void nvgpu_alloc_disable_dbg(struct nvgpu_allocator *a) { a->debug = false;