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 <nbenech@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2224526
Reviewed-by: Lakshmanan M <lm@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Nicolas Benech
2019-10-23 17:26:33 -04:00
committed by Alex Waterman
parent 4523ee2b14
commit d49848d4a1
3 changed files with 402 additions and 66 deletions

View File

@@ -23,23 +23,57 @@
#ifndef BITMAP_ALLOCATOR_PRIV_H
#define BITMAP_ALLOCATOR_PRIV_H
/**
* @file
*
* Implementation of a bitmap allocator.
*/
#include <nvgpu/rbtree.h>
#include <nvgpu/kmem.h>
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)
{

View File

@@ -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 <nvgpu/rbtree.h>
#include <nvgpu/list.h>
#include <nvgpu/static_analysis.h>
@@ -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)
{

View File

@@ -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,