mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 18:42:29 +03:00
It's preparing to add bellow CFLAGS:
-Werror -Wall -Wextra \
-Wmissing-braces -Wpointer-arith -Wundef \
-Wconversion -Wsign-conversion \
-Wformat-security \
-Wmissing-declarations -Wredundant-decls -Wimplicit-fallthrough
Jira GVSCI-11640
Signed-off-by: Richard Zhao <rizhao@nvidia.com>
Change-Id: I7a7afff85231aed52a20f77854c30fe5c755cae5
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2555058
Reviewed-by: Shashank Singh <shashsingh@nvidia.com>
Reviewed-by: Aparna Das <aparnad@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
859 lines
26 KiB
C
859 lines
26 KiB
C
/*
|
|
* Copyright (c) 2011-2022, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#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.
|
|
* One of the allocator function pointers takes advantage of this and allows the
|
|
* debug output to be directed either to nvgpu_log() or a seq_file.
|
|
*/
|
|
#include <linux/seq_file.h>
|
|
#endif
|
|
|
|
#include <nvgpu/log.h>
|
|
#include <nvgpu/lock.h>
|
|
#include <nvgpu/list.h>
|
|
#include <nvgpu/types.h>
|
|
#include <nvgpu/utils.h>
|
|
|
|
/*
|
|
* Enable this flag to get finer control over allocator debug messaging
|
|
* (see below).
|
|
*/
|
|
#if 0
|
|
#define ALLOCATOR_DEBUG_FINE
|
|
#endif
|
|
|
|
struct nvgpu_allocator;
|
|
struct nvgpu_alloc_carveout;
|
|
struct vm_gk20a;
|
|
struct gk20a;
|
|
|
|
#define NVGPU_ALLOC_NAME_LEN 32U
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* @brief Interface to allocate a memory region with specific starting
|
|
* address.
|
|
*
|
|
* @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);
|
|
|
|
/**
|
|
* @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);
|
|
|
|
/**
|
|
* @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);
|
|
|
|
/**
|
|
* @brief Interface to destroy allocator.
|
|
*
|
|
* @param[in] allocator Pointer to nvgpu allocator.
|
|
*/
|
|
void (*fini)(struct nvgpu_allocator *allocator);
|
|
|
|
#ifdef __KERNEL__
|
|
/**
|
|
* @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[NVGPU_ALLOC_NAME_LEN];
|
|
/**
|
|
* 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;
|
|
/**
|
|
* 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;
|
|
/**
|
|
* 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)
|
|
{
|
|
return (struct nvgpu_alloc_carveout *)
|
|
((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), \
|
|
.base = (local_base), \
|
|
.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
|
|
* special care has to be taken to ensure that allocations of similar PTE
|
|
* sizes are placed in the same PDE block. This allows the higher level
|
|
* 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.
|
|
*/
|
|
#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
|
|
* may still use kmalloc(). This prevents the possibility of long waits for
|
|
* pages when using alloc_page(). Currently only the bitmap allocator
|
|
* implements this functionality.
|
|
*
|
|
* Also note that if you accept this flag then you must also define the
|
|
* free_fixed() function. Since no meta-data is allocated to help free
|
|
* 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).
|
|
*/
|
|
#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
|
|
* inside internally allocated large pages.
|
|
*
|
|
* 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.
|
|
*/
|
|
#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.
|
|
*/
|
|
#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_NO_SCATTER_GATHER BIT64(4)
|
|
|
|
/** @}*/
|
|
|
|
/** Enumerated type used to identify various allocator types */
|
|
enum nvgpu_allocator_type {
|
|
BUDDY_ALLOCATOR = 0,
|
|
#ifdef CONFIG_NVGPU_DGPU
|
|
PAGE_ALLOCATOR,
|
|
#endif
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* @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.
|
|
* Valid flags are
|
|
* - GPU_ALLOC_GVA_SPACE
|
|
* - GPU_ALLOC_NO_ALLOC_PAGE
|
|
* - GPU_ALLOC_4K_VIDMEM_PAGES
|
|
* - GPU_ALLOC_FORCE_CONTIG
|
|
* - GPU_ALLOC_NO_SCATTER_GATHER
|
|
*
|
|
* Construct a buddy allocator in \a na. A buddy allocator manages memory by
|
|
* splitting all memory into "buddies" - pairs of adjacent blocks of memory.
|
|
* Each buddy can be further subdivided into buddies, again, allowing for
|
|
* arbitrary power-of-two sized blocks to be allocated.
|
|
*
|
|
* Call nvgpu_buddy_check_argument_limits() to check the validity of the
|
|
* inputs. This function verifies that the input arguments are valid for a
|
|
* buddy allocator. Specifically the #block_size of a buddy allocator must be
|
|
* a power-of-two, #max_order must be less than #GPU_BALLOC_MAX_ORDER,
|
|
* and size must be non-zero.
|
|
* Call nvgpu_alloc_common_init() to initialize the basic operations like
|
|
* allocation, free and query opearions for the respective allocator.
|
|
* Initialize some lists and locks to maintain the allocator objects.
|
|
*
|
|
* @return 0 in case of success, < 0 otherwise.
|
|
* @retval -EINVAL in case of incorrect input value.
|
|
* - When \a length is zero.
|
|
* - \a blk_size is not a power of two.
|
|
* - \a base and \a length is not aligned with \a blk_size.
|
|
* @retval -ENOMEM in case there is no 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);
|
|
|
|
/**
|
|
* @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.
|
|
* Valid flags are
|
|
* - GPU_ALLOC_GVA_SPACE
|
|
* - GPU_ALLOC_NO_ALLOC_PAGE
|
|
* - GPU_ALLOC_FORCE_CONTIG
|
|
* - GPU_ALLOC_NO_SCATTER_GATHER
|
|
*
|
|
* Call nvgpu_bitmap_check_argument_limits() to check the validity
|
|
* of input paramemeters. This function verifies the input parameters
|
|
* are valid specifically the #block_size of a bitmap allocator must be
|
|
* a power-of-two, #base and #length must be aligned with #blk_size.
|
|
* Call nvgpu_alloc_common_init() to initialize the basic operations like
|
|
* allocation, free and query opearions for the respective allocator.
|
|
* Initialize some lists and locks to maintain the allocator objects.
|
|
*
|
|
* @return 0 in case of success, < 0 otherwise.
|
|
* @retval -EINVAL in case of incorrect input value.
|
|
* - When \a length is zero.
|
|
* - \a blk_size is not a power of two.
|
|
* - \a base and \a length is not aligned with \a blk_size.
|
|
* @retval -ENOMEM in case there is no 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
|
|
|
|
/**
|
|
* @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. Valid
|
|
* flags are
|
|
* - GPU_ALLOC_GVA_SPACE
|
|
* - GPU_ALLOC_NO_ALLOC_PAGE
|
|
* - GPU_ALLOC_4K_VIDMEM_PAGES
|
|
* - GPU_ALLOC_FORCE_CONTIG
|
|
* - GPU_ALLOC_NO_SCATTER_GATHER
|
|
* @return 0 in case of success, < 0 otherwise.
|
|
* @retval -EINVAL in case of incorrect input value.
|
|
* @retval -ENOMEM in case there is no 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
|
|
|
|
/**
|
|
* @brief Common init function for any type of allocator.
|
|
*
|
|
* @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.
|
|
* Valid flags are
|
|
* - GPU_ALLOC_GVA_SPACE
|
|
* - GPU_ALLOC_NO_ALLOC_PAGE
|
|
* - GPU_ALLOC_4K_VIDMEM_PAGES
|
|
* - GPU_ALLOC_FORCE_CONTIG
|
|
* - GPU_ALLOC_NO_SCATTER_GATHER
|
|
* @param[in] alloc_type Allocator type. Valid types are
|
|
* - BUDDY_ALLOCATOR
|
|
* - PAGE_ALLOCATOR
|
|
* - BITMAP_ALLOCATOR
|
|
*
|
|
* Call *allocator_init() to initialize the respective allocators.
|
|
*
|
|
* @return 0 in case of success, < 0 otherwise.
|
|
* @retval -EINVAL in allocator type is not valid.
|
|
* @retval -EINVAL in case of incorrect input value.
|
|
* - When \a length is zero.
|
|
* - \a blk_size is not a power of two.
|
|
* - \a base and \a length is not aligned with \a blk_size.
|
|
* @retval -ENOMEM in case there is no enough memory for allocation.
|
|
*/
|
|
int nvgpu_allocator_init(struct gk20a *g, struct nvgpu_allocator *na,
|
|
struct vm_gk20a *vm, const char *name,
|
|
u64 base, u64 length, u64 blk_size, u64 max_order,
|
|
u64 flags, enum nvgpu_allocator_type alloc_type);
|
|
|
|
#ifdef CONFIG_NVGPU_FENCE
|
|
/**
|
|
* @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 no 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
|
|
|
|
/**
|
|
* @brief Interface to allocate resources.
|
|
*
|
|
* @param[in] a Pointer to nvgpu allocator.
|
|
* @param[in] len Size of allocation.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the alloc
|
|
* operation.
|
|
*
|
|
* @return Address of allocation in case of success,
|
|
* 0 otherwise.
|
|
* @retval 0 For the failure and reasons can be one of the following
|
|
* - input parameters are not valid.
|
|
* - There is no free space available in the allocator.
|
|
* - zalloc failure for no memory conditions.
|
|
*
|
|
*/
|
|
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.
|
|
*
|
|
*
|
|
* Invoke the underlying allocator's implementation of the alloc_pte
|
|
* operation.
|
|
*
|
|
* @return Address of allocation in case of success, 0 otherwise.
|
|
* @retval 0 For the failure and reasons can be one of the following
|
|
* - input parameters are not valid.
|
|
* - There is no free space available in the allocator.
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the free
|
|
* operation.
|
|
*
|
|
* @return None
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the alloc_fixed
|
|
* operation.
|
|
*
|
|
* @return Address of allocation in case of success.
|
|
* @retval 0 For failure, in any of the reasons below
|
|
* invalid inputs.
|
|
* space unavailability to satisfy the requirement.
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the free_fixed
|
|
* operation.
|
|
*
|
|
* @return None.
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the
|
|
* alloc_reserve_carveout operation.
|
|
*
|
|
* @return 0 in case of success, < 0 in case of failure.
|
|
* @retval -EINVAL For invalid input parameters.
|
|
* @retval -EBUSY For the unavailability of the base of the
|
|
* the carveout.
|
|
* @retval -ENOMEM For unavailability of the object.
|
|
*
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the release_carveout
|
|
* operation.
|
|
*
|
|
* @return None.
|
|
*/
|
|
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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the base operation.
|
|
*
|
|
* @return Allocator start address.
|
|
*/
|
|
u64 nvgpu_alloc_base(struct nvgpu_allocator *a);
|
|
|
|
/**
|
|
* @brief Interface to read allocator length.
|
|
*
|
|
* @param a Pointer to nvgpu allocator.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the length
|
|
* operation.
|
|
*
|
|
* @return Allocator length.
|
|
*/
|
|
u64 nvgpu_alloc_length(struct nvgpu_allocator *a);
|
|
|
|
/**
|
|
* @brief Interface to read allocator end address.
|
|
*
|
|
* @param[in] a Pointer to nvgpu allocator.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the end operation.
|
|
*
|
|
* @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.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the space
|
|
* operation.
|
|
*
|
|
* @return Available allocator space.
|
|
*
|
|
*/
|
|
u64 nvgpu_alloc_space(struct nvgpu_allocator *a);
|
|
|
|
/**
|
|
* @brief Interface to destroy allocator.
|
|
*
|
|
* @param[in] a Pointer to nvgpu allocator.
|
|
*
|
|
* Invoke the underlying allocator's implementation of the destroy
|
|
* operation.
|
|
*
|
|
* @return None.
|
|
*
|
|
*/
|
|
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;
|
|
}
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
/*
|
|
* 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);
|
|
#else
|
|
static inline void nvgpu_init_alloc_debug(struct gk20a *g,
|
|
struct nvgpu_allocator *a)
|
|
{
|
|
(void)g;
|
|
(void)a;
|
|
}
|
|
static inline void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a)
|
|
{
|
|
(void)a;
|
|
}
|
|
#endif /* CONFIG_DEBUG_FS */
|
|
|
|
/**
|
|
* @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.
|
|
* @retval -EINVAL For any of the inputs is NULL.
|
|
*
|
|
*/
|
|
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);
|
|
|
|
/*
|
|
* Debug stuff.
|
|
*/
|
|
#ifdef __KERNEL__
|
|
#define alloc_pstat(seq, allocator, fmt, arg...) \
|
|
do { \
|
|
if (seq) \
|
|
seq_printf(seq, fmt "\n", ##arg); \
|
|
else \
|
|
alloc_dbg(allocator, fmt, ##arg); \
|
|
} while (false)
|
|
#endif
|
|
|
|
#define do_alloc_dbg(a, fmt, arg...) \
|
|
nvgpu_log((a)->g, gpu_dbg_alloc, "%25s " fmt, (a)->name, ##arg)
|
|
|
|
/*
|
|
* This gives finer control over debugging messages. By defining the
|
|
* ALLOCATOR_DEBUG_FINE macro prints for an allocator will only get made if
|
|
* that allocator's debug flag is set.
|
|
*
|
|
* Otherwise debugging is as normal: debug statements for all allocators
|
|
* if the GPU debugging mask bit is set. Note: even when ALLOCATOR_DEBUG_FINE
|
|
* is set gpu_dbg_alloc must still also be set to true.
|
|
*/
|
|
#if defined(ALLOCATOR_DEBUG_FINE)
|
|
#define alloc_dbg(a, fmt, arg...) \
|
|
do { \
|
|
if ((a)->debug) \
|
|
do_alloc_dbg((a), fmt, ##arg); \
|
|
} while (false)
|
|
#else
|
|
#define alloc_dbg(a, fmt, arg...) do_alloc_dbg(a, fmt, ##arg)
|
|
#endif
|
|
|
|
#endif /* NVGPU_ALLOCATOR_H */
|