From d49848d4a11a7c4dc3158567f8e3ca8a0d3d4049 Mon Sep 17 00:00:00 2001 From: Nicolas Benech Date: Wed, 23 Oct 2019 17:26:33 -0400 Subject: [PATCH] gpu: nvgpu: doxygen: add documentation for allocators Improve Doxygen documentation for allocator.h and add Doxygen to bitmap_allocator_priv.h and buddy_allocator_priv.h. JIRA NVGPU-4035 Change-Id: I82fd30fe7768d6c1c0dd035e8be8d215ddd23565 Signed-off-by: Nicolas Benech Reviewed-on: https://git-master.nvidia.com/r/2224526 Reviewed-by: Lakshmanan M GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../mm/allocators/bitmap_allocator_priv.h | 118 +++++- .../mm/allocators/buddy_allocator_priv.h | 336 +++++++++++++++--- drivers/gpu/nvgpu/include/nvgpu/allocator.h | 14 + 3 files changed, 402 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/nvgpu/common/mm/allocators/bitmap_allocator_priv.h b/drivers/gpu/nvgpu/common/mm/allocators/bitmap_allocator_priv.h index 1750447d7..f0bf8dd90 100644 --- a/drivers/gpu/nvgpu/common/mm/allocators/bitmap_allocator_priv.h +++ b/drivers/gpu/nvgpu/common/mm/allocators/bitmap_allocator_priv.h @@ -23,23 +23,57 @@ #ifndef BITMAP_ALLOCATOR_PRIV_H #define BITMAP_ALLOCATOR_PRIV_H +/** + * @file + * + * Implementation of a bitmap allocator. + */ #include #include struct nvgpu_allocator; +/** + * Structure to hold the implementation details of the bitmap allocator. + */ struct nvgpu_bitmap_allocator { + /** + * Pointer to the common allocator structure. + */ struct nvgpu_allocator *owner; - u64 base; /* Base address of the space. */ - u64 length; /* Length of the space. */ - u64 blk_size; /* Size that corresponds to 1 bit. */ - u64 blk_shift; /* Bit shift to divide by blk_size. */ - u64 num_bits; /* Number of allocatable bits. */ - u64 bit_offs; /* Offset of bitmap. */ + /** + * Base address of the space. + */ + u64 base; - /* + /** + * Length of the space. + */ + u64 length; + + /** + * Size that corresponds to 1 bit. + */ + u64 blk_size; + + /** + * Bit shift to divide by blk_size. + */ + u64 blk_shift; + + /** + * Number of allocatable bits. + */ + u64 num_bits; + + /** + * Offset of bitmap. + */ + u64 bit_offs; + + /** * Optimization for making repeated allocations faster. Keep track of * the next bit after the most recent allocation. This is where the next * search will start from. This should make allocation faster in cases @@ -48,28 +82,82 @@ struct nvgpu_bitmap_allocator { */ u64 next_blk; - unsigned long *bitmap; /* The actual bitmap! */ - struct nvgpu_rbtree_node *allocs; /* Tree of outstanding allocations */ + /** + * The actual bitmap used for allocations. + */ + unsigned long *bitmap; + /** + * Tree of outstanding allocations. + */ + struct nvgpu_rbtree_node *allocs; + + /** + * Metadata cache of allocations (contains address and size of + * allocations). + */ struct nvgpu_kmem_cache *meta_data_cache; + /** + * Configuration flags of the allocator. See \a GPU_ALLOC_* flags. + */ u64 flags; + /** + * Boolean to indicate if the allocator has been fully initialized. + */ bool inited; - /* Statistics */ + /** + * Statistics: track the number of non-fixed allocations. + */ u64 nr_allocs; + + /** + * Statistics: track the number of fixed allocations. + */ u64 nr_fixed_allocs; + + /** + * Statistics: total number of bytes allocated for both fixed and non- + * fixed allocations. + */ u64 bytes_alloced; + + /** + * Statistics: total number of bytes freed for both fixed and non-fixed + * allocations. + */ u64 bytes_freed; }; +/** + * Structure to hold the allocation metadata. + */ struct nvgpu_bitmap_alloc { + /** + * Base address of the allocation. + */ u64 base; + + /** + * Size of the allocation. + */ u64 length; - struct nvgpu_rbtree_node alloc_entry; /* RB tree of allocations. */ + + /** + * RB tree of allocations. + */ + struct nvgpu_rbtree_node alloc_entry; }; +/** + * @brief Given a tree node, retrieve the metdata of the allocation. + * + * @param[in] node Pointer to the tree node. + * + * @return pointer to the struct nvgpu_bitmap_alloc of the node. + */ static inline struct nvgpu_bitmap_alloc * nvgpu_bitmap_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) { @@ -77,6 +165,14 @@ nvgpu_bitmap_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) ((uintptr_t)node - offsetof(struct nvgpu_bitmap_alloc, alloc_entry)); }; +/** + * @brief Given a generic allocator context, retrieve a pointer to the bitmap + * allocator context structure. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return pointer to the struct nvgpu_bitmap_allocator. + */ static inline struct nvgpu_bitmap_allocator *bitmap_allocator( struct nvgpu_allocator *a) { diff --git a/drivers/gpu/nvgpu/common/mm/allocators/buddy_allocator_priv.h b/drivers/gpu/nvgpu/common/mm/allocators/buddy_allocator_priv.h index 2de8a86a9..bd34477fa 100644 --- a/drivers/gpu/nvgpu/common/mm/allocators/buddy_allocator_priv.h +++ b/drivers/gpu/nvgpu/common/mm/allocators/buddy_allocator_priv.h @@ -23,6 +23,12 @@ #ifndef NVGPU_MM_BUDDY_ALLOCATOR_PRIV_H #define NVGPU_MM_BUDDY_ALLOCATOR_PRIV_H +/** + * @file + * + * Implementation of the buddy allocator. + */ + #include #include #include @@ -31,38 +37,98 @@ struct nvgpu_kmem_cache; struct nvgpu_allocator; struct vm_gk20a; -/* - * Each buddy is an element in a binary tree. +/** + * Structure that defines each buddy as an element in a binary tree. */ struct nvgpu_buddy { - struct nvgpu_buddy *parent; /* Parent node. */ - struct nvgpu_buddy *buddy; /* This node's buddy. */ - struct nvgpu_buddy *left; /* Lower address sub-node. */ - struct nvgpu_buddy *right; /* Higher address sub-node. */ + /** + * Parent node. + */ + struct nvgpu_buddy *parent; - struct nvgpu_list_node buddy_entry; /* List entry for various lists. */ - struct nvgpu_rbtree_node alloced_entry; /* RB tree of allocations. */ + /** + * This node's buddy. + */ + struct nvgpu_buddy *buddy; - u64 start; /* Start address of this buddy. */ - u64 end; /* End address of this buddy. */ - u64 order; /* Buddy order. */ + /** + * Lower address sub-node. + */ + struct nvgpu_buddy *left; + /** + * Higher address sub-node. + */ + struct nvgpu_buddy *right; + + /** + * List entry for various lists. + */ + struct nvgpu_list_node buddy_entry; + + /** + * RB tree of allocations. + */ + struct nvgpu_rbtree_node alloced_entry; + + /** + * Start address of this buddy. + */ + u64 start; + + /** + * End address of this buddy. + */ + u64 end; + + /** + * Buddy order. + */ + u64 order; + + /** + * Possible flags to use in the buddy allocator. Set in the #flags + * member. + * @addtogroup BALLOC_BUDDY_FLAGS + * @{ + */ #define BALLOC_BUDDY_ALLOCED 0x1U #define BALLOC_BUDDY_SPLIT 0x2U #define BALLOC_BUDDY_IN_LIST 0x4U - u32 flags; /* List of associated flags. */ + /**@}*/ - /* - * Size of the PDE this buddy is using. This allows for grouping like - * sized allocations into the same PDE. + /** + * Buddy flags among the @ref BALLOC_BUDDY_FLAGS + */ + u32 flags; + + + /** + * Possible PDE sizes. This allows for grouping like sized allocations + * into the same PDE. Set in the #pte_size member. + * @addtogroup BALLOC_PTE_SIZE + * @{ */ #define BALLOC_PTE_SIZE_ANY (~0U) #define BALLOC_PTE_SIZE_INVALID 0U #define BALLOC_PTE_SIZE_SMALL 1U #define BALLOC_PTE_SIZE_BIG 2U + /**@}*/ + + /** + * Size of the PDE this buddy is using. Possible values in + * @ref BALLOC_PTE_SIZE + */ u32 pte_size; }; +/** + * @brief Given a list node, retrieve the buddy. + * + * @param[in] node Pointer to the list node. + * + * @return pointer to the struct nvgpu_buddy of the node. + */ static inline struct nvgpu_buddy * nvgpu_buddy_from_buddy_entry(struct nvgpu_list_node *node) { @@ -70,6 +136,13 @@ nvgpu_buddy_from_buddy_entry(struct nvgpu_list_node *node) ((uintptr_t)node - offsetof(struct nvgpu_buddy, buddy_entry)); }; +/** + * @brief Given a tree node, retrieve the buddy. + * + * @param[in] node Pointer to the tree node. + * + * @return pointer to the struct nvgpu_buddy of the node. + */ static inline struct nvgpu_buddy * nvgpu_buddy_from_rbtree_node(struct nvgpu_rbtree_node *node) { @@ -77,6 +150,29 @@ nvgpu_buddy_from_rbtree_node(struct nvgpu_rbtree_node *node) ((uintptr_t)node - offsetof(struct nvgpu_buddy, alloced_entry)); }; +/** + * @brief Macro generator to create is/set/clr operations for each of the + * flags in @ref BALLOC_BUDDY_FLAGS. + * + * The created functions are: + * + * bool buddy_is_alloced(struct nvgpu_buddy *b); + * void buddy_set_alloced(struct nvgpu_buddy *b); + * void buddy_clr_alloced(struct nvgpu_buddy *b); + * + * bool buddy_is_split(struct nvgpu_buddy *b); + * void buddy_set_split(struct nvgpu_buddy *b); + * void buddy_clr_split(struct nvgpu_buddy *b); + * + * bool buddy_is_in_list(struct nvgpu_buddy *b); + * void buddy_set_in_list(struct nvgpu_buddy *b); + * void buddy_clr_in_list(struct nvgpu_buddy *b); + * + * @param[in] flag One of is, set or clr + * @param[in] flag_up One of the @ref BALLOC_BUDDY_FLAGS + * + * @{ + */ #define nvgpu_buddy_allocator_flag_ops(flag, flag_up) \ static inline bool buddy_is_ ## flag(struct nvgpu_buddy *b) \ { \ @@ -91,34 +187,40 @@ nvgpu_buddy_from_rbtree_node(struct nvgpu_rbtree_node *node) b->flags &= ~BALLOC_BUDDY_ ## flag_up; \ } -/* - * bool buddy_is_alloced(struct nvgpu_buddy *b); - * void buddy_set_alloced(struct nvgpu_buddy *b); - * void buddy_clr_alloced(struct nvgpu_buddy *b); - * - * bool buddy_is_split(struct nvgpu_buddy *b); - * void buddy_set_split(struct nvgpu_buddy *b); - * void buddy_clr_split(struct nvgpu_buddy *b); - * - * bool buddy_is_in_list(struct nvgpu_buddy *b); - * void buddy_set_in_list(struct nvgpu_buddy *b); - * void buddy_clr_in_list(struct nvgpu_buddy *b); - */ nvgpu_buddy_allocator_flag_ops(alloced, ALLOCED); nvgpu_buddy_allocator_flag_ops(split, SPLIT); nvgpu_buddy_allocator_flag_ops(in_list, IN_LIST); +/**@} */ -/* - * Keeps info for a fixed allocation. +/** + * Structure to keep information for a fixed allocation. */ struct nvgpu_fixed_alloc { - struct nvgpu_list_node buddies; /* List of buddies. */ - struct nvgpu_rbtree_node alloced_entry; /* RB tree of fixed allocations. */ - - u64 start; /* Start of fixed block. */ - u64 end; /* End address. */ + /** + * List of buddies. + */ + struct nvgpu_list_node buddies; + /** + * RB tree of fixed allocations. + */ + struct nvgpu_rbtree_node alloced_entry; + /** + * Start of fixed block. + */ + u64 start; + /** + * End address. + */ + u64 end; }; +/** + * @brief Given a tree node, retrieve the fixed allocation. + * + * @param[in] node Pointer to the tree node. + * + * @return pointer to the struct nvgpu_fixed_alloc of the node. + */ static inline struct nvgpu_fixed_alloc * nvgpu_fixed_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) { @@ -126,7 +228,7 @@ nvgpu_fixed_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) ((uintptr_t)node - offsetof(struct nvgpu_fixed_alloc, alloced_entry)); }; -/* +/** * GPU buddy allocator for the various GPU address spaces. Each addressable unit * doesn't have to correspond to a byte. In some cases each unit is a more * complex object such as a comp_tag line or the like. @@ -134,88 +236,212 @@ nvgpu_fixed_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) * The max order is computed based on the size of the minimum order and the size * of the address space. * - * order_size is the size of an order 0 buddy. + * #blk_size is the size of an order 0 buddy. */ struct nvgpu_buddy_allocator { - struct nvgpu_allocator *owner; /* Owner of this buddy allocator. */ - struct vm_gk20a *vm; /* Parent VM - can be NULL. */ + /** + * Pointer to the common allocator structure. + */ + struct nvgpu_allocator *owner; + /** + * Parent VM - can be NULL. + */ + struct vm_gk20a *vm; - u64 base; /* Base address of the space. */ - u64 length; /* Length of the space. */ - u64 blk_size; /* Size of order 0 allocation. */ - u64 blk_shift; /* Shift to divide by blk_size. */ + /** + * Base address of the space. + */ + u64 base; + /** + * Length of the space. + */ + u64 length; + /** + * Size of order 0 allocation. + */ + u64 blk_size; + /** + * Shift to divide by blk_size. + */ + u64 blk_shift; - /* Internal stuff. */ - u64 start; /* Real start (aligned to blk_size). */ - u64 end; /* Real end, trimmed if needed. */ - u64 count; /* Count of objects in space. */ - u64 blks; /* Count of blks in the space. */ - u64 max_order; /* Specific maximum order. */ + /** + * Internal: real start (aligned to #blk_size). + */ + u64 start; + /** + * Internal: real end, trimmed if needed. + */ + u64 end; + /** + * Internal: count of objects in space. + */ + u64 count; + /** + * Internal: count of blks in the space. + */ + u64 blks; + /** + * Internal: specific maximum order. + */ + u64 max_order; - struct nvgpu_rbtree_node *alloced_buddies; /* Outstanding allocations. */ - struct nvgpu_rbtree_node *fixed_allocs; /* Outstanding fixed allocations. */ + /** + * Outstanding allocations. + */ + struct nvgpu_rbtree_node *alloced_buddies; + /** + * Outstanding fixed allocations. + */ + struct nvgpu_rbtree_node *fixed_allocs; + /** + * List of carveouts. + */ struct nvgpu_list_node co_list; + /** + * Cache of allocations (contains address and size of allocations). + */ struct nvgpu_kmem_cache *buddy_cache; - /* + /** * Impose an upper bound on the maximum order. */ #define GPU_BALLOC_ORDER_LIST_LEN (GPU_BALLOC_MAX_ORDER + 1U) + /** + * List of buddies. + */ struct nvgpu_list_node buddy_list[GPU_BALLOC_ORDER_LIST_LEN]; + /** + * Length of the buddy list. + */ u64 buddy_list_len[GPU_BALLOC_ORDER_LIST_LEN]; + /** + * Number of split nodes. + */ u64 buddy_list_split[GPU_BALLOC_ORDER_LIST_LEN]; + /** + * Number of allocated nodes. + */ u64 buddy_list_alloced[GPU_BALLOC_ORDER_LIST_LEN]; - /* + /** * This is for when the allocator is managing a GVA space (the - * GPU_ALLOC_GVA_SPACE bit is set in @flags). This requires + * #GPU_ALLOC_GVA_SPACE bit is set in #flags). This requires * that we group like sized allocations into PDE blocks. */ u64 pte_blk_order; + /** + * Boolean to indicate if the allocator has been fully initialized. + */ bool initialized; - bool alloc_made; /* True after the first alloc. */ + /** + * Boolean set to true after the first allocation is made. + */ + bool alloc_made; + /** + * Flags in used by the allocator as defined by @ref GPU_ALLOC_FLAGS + */ u64 flags; + /** + * Statistics: total number of bytes allocated. + */ u64 bytes_alloced; + /** + * Statistics: total number of bytes allocated taking into account the + * buddy order. + */ u64 bytes_alloced_real; + /** + * Statistics: total number of bytes freed. + */ u64 bytes_freed; }; +/** + * @brief Given a generic allocator context, retrieve a pointer to the buddy + * allocator context structure. + * + * @param[in] a Pointer to nvgpu allocator. + * + * @return pointer to the struct nvgpu_bitmap_allocator. + */ static inline struct nvgpu_buddy_allocator *buddy_allocator( struct nvgpu_allocator *a) { return (struct nvgpu_buddy_allocator *)(a)->priv; } +/** + * @brief Given a buddy allocator, retrieve the list of buddies of the chosen + * order. + * + * @param[in] a Pointer to the buddy allocator. + * @param[in] order Buddy order. + * + * @return list of buddies whose order is \a order. + */ static inline struct nvgpu_list_node *balloc_get_order_list( struct nvgpu_buddy_allocator *a, u64 order) { return &a->buddy_list[order]; } +/** + * @brief Convert a buddy order to a length in bytes, based on the block size. + * + * @param[in] a Pointer to the buddy allocator. + * @param[in] order Buddy order. + * + * @return length in bytes. + */ static inline u64 balloc_order_to_len(struct nvgpu_buddy_allocator *a, u64 order) { return nvgpu_safe_mult_u64(BIT64(order), a->blk_size); } +/** + * @brief Given a base address, shift it by the base address of the buddy. + * + * @param[in] a Pointer to the buddy allocator. + * @param[in] order Base address. + * + * @return shifted address. + */ static inline u64 balloc_base_shift(struct nvgpu_buddy_allocator *a, u64 base) { return nvgpu_safe_sub_u64(base, a->start); } +/** + * @brief Given a shifted address, unshift it by the base address of the buddy. + * + * @param[in] a Pointer to the buddy allocator. + * @param[in] order Shifted address. + * + * @return unshifted address. + */ static inline u64 balloc_base_unshift(struct nvgpu_buddy_allocator *a, u64 base) { return nvgpu_safe_add_u64(base, a->start); } +/** + * @brief Given a buddy allocator context, retrieve a pointer to the generic + * allocator context structure. + * + * @param[in] a Pointer to nvgpu buddy allocator. + * + * @return pointer to the struct nvgpu_allocator. + */ static inline struct nvgpu_allocator *balloc_owner( struct nvgpu_buddy_allocator *a) { diff --git a/drivers/gpu/nvgpu/include/nvgpu/allocator.h b/drivers/gpu/nvgpu/include/nvgpu/allocator.h index 8085db3a5..382b19625 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/allocator.h +++ b/drivers/gpu/nvgpu/include/nvgpu/allocator.h @@ -23,6 +23,12 @@ #ifndef NVGPU_ALLOCATOR_H #define NVGPU_ALLOCATOR_H +/** + * @file + * + * Allocator interface. + */ + #ifdef __KERNEL__ /* * The Linux kernel has this notion of seq_files for printing info to userspace. @@ -288,6 +294,12 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) .length = (local_length) \ } +/** + * Possible GPU allocation flags. + * @addtogroup GPU_ALLOC_FLAGS + * @{ + */ + /** * 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 @@ -342,6 +354,8 @@ nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) */ #define GPU_ALLOC_NO_SCATTER_GATHER BIT64(4) +/** @}*/ + /** Enumerated type used to identify various allocator types */ enum nvgpu_allocator_type { BUDDY_ALLOCATOR = 0,