mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-05 09:57:21 +02:00
gpu: Move DRM buddy allocator one level up (part two)
Move the DRM buddy allocator one level up so that it can be used by GPU drivers (example, nova-core) that have usecases other than DRM (such as VFIO vGPU support). Modify the API, structures and Kconfigs to use "gpu_buddy" terminology. Adapt the drivers and tests to use the new API. The commit cannot be split due to bisectability, however no functional change is intended. Verified by running K-UNIT tests and build tested various configurations. Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com> Reviewed-by: Dave Airlie <airlied@redhat.com> [airlied: I've split this into two so git can find copies easier. I've also just nuked drm_random library, that stuff needs to be done elsewhere and only the buddy tests seem to be using it]. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
committed by
Dave Airlie
parent
4a9671a03f
commit
ba110db8e1
@@ -532,6 +532,12 @@ Buddy Allocator Function References (GPU buddy)
|
||||
.. kernel-doc:: drivers/gpu/buddy.c
|
||||
:export:
|
||||
|
||||
DRM Buddy Specific Logging Function References
|
||||
----------------------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_buddy.c
|
||||
:export:
|
||||
|
||||
DRM Cache Handling and Fast WC memcpy()
|
||||
=======================================
|
||||
|
||||
|
||||
+5
-3
@@ -8797,15 +8797,17 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: drivers/gpu/drm/ttm/
|
||||
F: include/drm/ttm/
|
||||
|
||||
DRM BUDDY ALLOCATOR
|
||||
GPU BUDDY ALLOCATOR
|
||||
M: Matthew Auld <matthew.auld@intel.com>
|
||||
M: Arun Pravin <arunpravin.paneerselvam@amd.com>
|
||||
R: Christian Koenig <christian.koenig@amd.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: drivers/gpu/drm/drm_buddy.c
|
||||
F: drivers/gpu/drm/tests/drm_buddy_test.c
|
||||
F: drivers/gpu/drm_buddy.c
|
||||
F: drivers/gpu/buddy.c
|
||||
F: drivers/gpu/tests/gpu_buddy_test.c
|
||||
F: include/linux/gpu_buddy.h
|
||||
F: include/drm/drm_buddy.h
|
||||
|
||||
DRM AUTOMATED TESTING
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config GPU_BUDDY
|
||||
bool
|
||||
help
|
||||
A page based buddy allocator for GPU memory.
|
||||
|
||||
config GPU_BUDDY_KUNIT_TEST
|
||||
tristate "KUnit tests for GPU buddy allocator" if !KUNIT_ALL_TESTS
|
||||
depends on GPU_BUDDY && KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
KUnit tests for the GPU buddy allocator.
|
||||
@@ -6,3 +6,4 @@ obj-y += host1x/ drm/ vga/ tests/
|
||||
obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
|
||||
obj-$(CONFIG_TRACE_GPU_MEM) += trace/
|
||||
obj-$(CONFIG_NOVA_CORE) += nova-core/
|
||||
obj-$(CONFIG_GPU_BUDDY) += buddy.o
|
||||
|
||||
+271
-285
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,7 @@ config DRM_GPUSVM
|
||||
config DRM_BUDDY
|
||||
tristate
|
||||
depends on DRM
|
||||
select GPU_BUDDY
|
||||
help
|
||||
A page based buddy allocator
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ drm_gpusvm_helper-$(CONFIG_ZONE_DEVICE) += \
|
||||
|
||||
obj-$(CONFIG_DRM_GPUSVM) += drm_gpusvm_helper.o
|
||||
|
||||
obj-$(CONFIG_DRM_BUDDY) += ../buddy.o
|
||||
obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
|
||||
|
||||
drm_dma_helper-y := drm_gem_dma_helper.o
|
||||
drm_dma_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_dma.o
|
||||
|
||||
@@ -5663,7 +5663,7 @@ int amdgpu_ras_add_critical_region(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct amdgpu_vram_mgr_resource *vres;
|
||||
struct ras_critical_region *region;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
int ret = 0;
|
||||
|
||||
if (!bo || !bo->tbo.resource)
|
||||
|
||||
@@ -55,7 +55,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
|
||||
uint64_t start, uint64_t size,
|
||||
struct amdgpu_res_cursor *cur)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct list_head *head, *next;
|
||||
struct drm_mm_node *node;
|
||||
|
||||
@@ -71,7 +71,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
|
||||
head = &to_amdgpu_vram_mgr_resource(res)->blocks;
|
||||
|
||||
block = list_first_entry_or_null(head,
|
||||
struct drm_buddy_block,
|
||||
struct gpu_buddy_block,
|
||||
link);
|
||||
if (!block)
|
||||
goto fallback;
|
||||
@@ -81,7 +81,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
|
||||
|
||||
next = block->link.next;
|
||||
if (next != head)
|
||||
block = list_entry(next, struct drm_buddy_block, link);
|
||||
block = list_entry(next, struct gpu_buddy_block, link);
|
||||
}
|
||||
|
||||
cur->start = amdgpu_vram_mgr_block_start(block) + start;
|
||||
@@ -125,7 +125,7 @@ fallback:
|
||||
*/
|
||||
static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct drm_mm_node *node;
|
||||
struct list_head *next;
|
||||
|
||||
@@ -146,7 +146,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
|
||||
block = cur->node;
|
||||
|
||||
next = block->link.next;
|
||||
block = list_entry(next, struct drm_buddy_block, link);
|
||||
block = list_entry(next, struct gpu_buddy_block, link);
|
||||
|
||||
cur->node = block;
|
||||
cur->start = amdgpu_vram_mgr_block_start(block);
|
||||
@@ -175,7 +175,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
|
||||
*/
|
||||
static inline bool amdgpu_res_cleared(struct amdgpu_res_cursor *cur)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
switch (cur->mem_type) {
|
||||
case TTM_PL_VRAM:
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <drm/ttm/ttm_range_manager.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_buddy.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_vm.h"
|
||||
@@ -52,15 +53,15 @@ to_amdgpu_device(struct amdgpu_vram_mgr *mgr)
|
||||
return container_of(mgr, struct amdgpu_device, mman.vram_mgr);
|
||||
}
|
||||
|
||||
static inline struct drm_buddy_block *
|
||||
static inline struct gpu_buddy_block *
|
||||
amdgpu_vram_mgr_first_block(struct list_head *list)
|
||||
{
|
||||
return list_first_entry_or_null(list, struct drm_buddy_block, link);
|
||||
return list_first_entry_or_null(list, struct gpu_buddy_block, link);
|
||||
}
|
||||
|
||||
static inline bool amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 start, size;
|
||||
|
||||
block = amdgpu_vram_mgr_first_block(head);
|
||||
@@ -71,7 +72,7 @@ static inline bool amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head)
|
||||
start = amdgpu_vram_mgr_block_start(block);
|
||||
size = amdgpu_vram_mgr_block_size(block);
|
||||
|
||||
block = list_entry(block->link.next, struct drm_buddy_block, link);
|
||||
block = list_entry(block->link.next, struct gpu_buddy_block, link);
|
||||
if (start + size != amdgpu_vram_mgr_block_start(block))
|
||||
return false;
|
||||
}
|
||||
@@ -81,7 +82,7 @@ static inline bool amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head)
|
||||
|
||||
static inline u64 amdgpu_vram_mgr_blocks_size(struct list_head *head)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 size = 0;
|
||||
|
||||
list_for_each_entry(block, head, link)
|
||||
@@ -254,7 +255,7 @@ const struct attribute_group amdgpu_vram_mgr_attr_group = {
|
||||
* Calculate how many bytes of the DRM BUDDY block are inside visible VRAM
|
||||
*/
|
||||
static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev,
|
||||
struct drm_buddy_block *block)
|
||||
struct gpu_buddy_block *block)
|
||||
{
|
||||
u64 start = amdgpu_vram_mgr_block_start(block);
|
||||
u64 end = start + amdgpu_vram_mgr_block_size(block);
|
||||
@@ -279,7 +280,7 @@ u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo)
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
struct ttm_resource *res = bo->tbo.resource;
|
||||
struct amdgpu_vram_mgr_resource *vres = to_amdgpu_vram_mgr_resource(res);
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 usage = 0;
|
||||
|
||||
if (amdgpu_gmc_vram_full_visible(&adev->gmc))
|
||||
@@ -299,15 +300,15 @@ static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct amdgpu_device *adev = to_amdgpu_device(mgr);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct amdgpu_vram_reservation *rsv, *temp;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
uint64_t vis_usage;
|
||||
|
||||
list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, blocks) {
|
||||
if (drm_buddy_alloc_blocks(mm, rsv->start, rsv->start + rsv->size,
|
||||
if (gpu_buddy_alloc_blocks(mm, rsv->start, rsv->start + rsv->size,
|
||||
rsv->size, mm->chunk_size, &rsv->allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION))
|
||||
GPU_BUDDY_RANGE_ALLOCATION))
|
||||
continue;
|
||||
|
||||
block = amdgpu_vram_mgr_first_block(&rsv->allocated);
|
||||
@@ -403,7 +404,7 @@ int amdgpu_vram_mgr_query_address_block_info(struct amdgpu_vram_mgr *mgr,
|
||||
uint64_t address, struct amdgpu_vram_block_info *info)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *vres;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 start, size;
|
||||
int ret = -ENOENT;
|
||||
|
||||
@@ -450,8 +451,8 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
struct amdgpu_vram_mgr_resource *vres;
|
||||
u64 size, remaining_size, lpfn, fpfn;
|
||||
unsigned int adjust_dcc_size = 0;
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
unsigned long pages_per_block;
|
||||
int r;
|
||||
|
||||
@@ -493,17 +494,17 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
INIT_LIST_HEAD(&vres->blocks);
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_TOPDOWN_ALLOCATION;
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
|
||||
vres->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED)
|
||||
vres->flags |= DRM_BUDDY_CLEAR_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_CLEAR_ALLOCATION;
|
||||
|
||||
if (fpfn || lpfn != mgr->mm.size)
|
||||
/* Allocate blocks in desired range */
|
||||
vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_RANGE_ALLOCATION;
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC &&
|
||||
adev->gmc.gmc_funcs->get_dcc_alignment)
|
||||
@@ -516,7 +517,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
dcc_size = roundup_pow_of_two(vres->base.size + adjust_dcc_size);
|
||||
remaining_size = (u64)dcc_size;
|
||||
|
||||
vres->flags |= DRM_BUDDY_TRIM_DISABLE;
|
||||
vres->flags |= GPU_BUDDY_TRIM_DISABLE;
|
||||
}
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
@@ -536,7 +537,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
|
||||
BUG_ON(min_block_size < mm->chunk_size);
|
||||
|
||||
r = drm_buddy_alloc_blocks(mm, fpfn,
|
||||
r = gpu_buddy_alloc_blocks(mm, fpfn,
|
||||
lpfn,
|
||||
size,
|
||||
min_block_size,
|
||||
@@ -545,7 +546,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
|
||||
if (unlikely(r == -ENOSPC) && pages_per_block == ~0ul &&
|
||||
!(place->flags & TTM_PL_FLAG_CONTIGUOUS)) {
|
||||
vres->flags &= ~DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
vres->flags &= ~GPU_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
pages_per_block = max_t(u32, 2UL << (20UL - PAGE_SHIFT),
|
||||
tbo->page_alignment);
|
||||
|
||||
@@ -566,7 +567,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
list_add_tail(&vres->vres_node, &mgr->allocated_vres_list);
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS && adjust_dcc_size) {
|
||||
struct drm_buddy_block *dcc_block;
|
||||
struct gpu_buddy_block *dcc_block;
|
||||
unsigned long dcc_start;
|
||||
u64 trim_start;
|
||||
|
||||
@@ -576,7 +577,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
roundup((unsigned long)amdgpu_vram_mgr_block_start(dcc_block),
|
||||
adjust_dcc_size);
|
||||
trim_start = (u64)dcc_start;
|
||||
drm_buddy_block_trim(mm, &trim_start,
|
||||
gpu_buddy_block_trim(mm, &trim_start,
|
||||
(u64)vres->base.size,
|
||||
&vres->blocks);
|
||||
}
|
||||
@@ -614,7 +615,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
return 0;
|
||||
|
||||
error_free_blocks:
|
||||
drm_buddy_free_list(mm, &vres->blocks, 0);
|
||||
gpu_buddy_free_list(mm, &vres->blocks, 0);
|
||||
mutex_unlock(&mgr->lock);
|
||||
error_fini:
|
||||
ttm_resource_fini(man, &vres->base);
|
||||
@@ -637,8 +638,8 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
|
||||
struct amdgpu_vram_mgr_resource *vres = to_amdgpu_vram_mgr_resource(res);
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct amdgpu_device *adev = to_amdgpu_device(mgr);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
uint64_t vis_usage = 0;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
@@ -649,7 +650,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
|
||||
list_for_each_entry(block, &vres->blocks, link)
|
||||
vis_usage += amdgpu_vram_mgr_vis_size(adev, block);
|
||||
|
||||
drm_buddy_free_list(mm, &vres->blocks, vres->flags);
|
||||
gpu_buddy_free_list(mm, &vres->blocks, vres->flags);
|
||||
amdgpu_vram_mgr_do_reserve(man);
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
@@ -688,7 +689,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
|
||||
if (!*sgt)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Determine the number of DRM_BUDDY blocks to export */
|
||||
/* Determine the number of GPU_BUDDY blocks to export */
|
||||
amdgpu_res_first(res, offset, length, &cursor);
|
||||
while (cursor.remaining) {
|
||||
num_entries++;
|
||||
@@ -704,10 +705,10 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
|
||||
sg->length = 0;
|
||||
|
||||
/*
|
||||
* Walk down DRM_BUDDY blocks to populate scatterlist nodes
|
||||
* @note: Use iterator api to get first the DRM_BUDDY block
|
||||
* Walk down GPU_BUDDY blocks to populate scatterlist nodes
|
||||
* @note: Use iterator api to get first the GPU_BUDDY block
|
||||
* and the number of bytes from it. Access the following
|
||||
* DRM_BUDDY block(s) if more buffer needs to exported
|
||||
* GPU_BUDDY block(s) if more buffer needs to exported
|
||||
*/
|
||||
amdgpu_res_first(res, offset, length, &cursor);
|
||||
for_each_sgtable_sg((*sgt), sg, i) {
|
||||
@@ -792,10 +793,10 @@ uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr)
|
||||
void amdgpu_vram_mgr_clear_reset_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
drm_buddy_reset_clear(mm, false);
|
||||
gpu_buddy_reset_clear(mm, false);
|
||||
mutex_unlock(&mgr->lock);
|
||||
}
|
||||
|
||||
@@ -815,7 +816,7 @@ static bool amdgpu_vram_mgr_intersects(struct ttm_resource_manager *man,
|
||||
size_t size)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &mgr->blocks, link) {
|
||||
@@ -848,7 +849,7 @@ static bool amdgpu_vram_mgr_compatible(struct ttm_resource_manager *man,
|
||||
size_t size)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &mgr->blocks, link) {
|
||||
@@ -877,7 +878,7 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
|
||||
struct drm_printer *printer)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct amdgpu_vram_reservation *rsv;
|
||||
|
||||
drm_printf(printer, " vis usage:%llu\n",
|
||||
@@ -930,7 +931,7 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
|
||||
mgr->default_page_size = PAGE_SIZE;
|
||||
|
||||
man->func = &amdgpu_vram_mgr_func;
|
||||
err = drm_buddy_init(&mgr->mm, man->size, PAGE_SIZE);
|
||||
err = gpu_buddy_init(&mgr->mm, man->size, PAGE_SIZE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -965,11 +966,11 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
|
||||
kfree(rsv);
|
||||
|
||||
list_for_each_entry_safe(rsv, temp, &mgr->reserved_pages, blocks) {
|
||||
drm_buddy_free_list(&mgr->mm, &rsv->allocated, 0);
|
||||
gpu_buddy_free_list(&mgr->mm, &rsv->allocated, 0);
|
||||
kfree(rsv);
|
||||
}
|
||||
if (!adev->gmc.is_app_apu)
|
||||
drm_buddy_fini(&mgr->mm);
|
||||
gpu_buddy_fini(&mgr->mm);
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
ttm_resource_manager_cleanup(man);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
struct amdgpu_vram_mgr {
|
||||
struct ttm_resource_manager manager;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
/* protects access to buffer objects */
|
||||
struct mutex lock;
|
||||
struct list_head reservations_pending;
|
||||
@@ -57,19 +57,19 @@ struct amdgpu_vram_mgr_resource {
|
||||
struct amdgpu_vres_task task;
|
||||
};
|
||||
|
||||
static inline u64 amdgpu_vram_mgr_block_start(struct drm_buddy_block *block)
|
||||
static inline u64 amdgpu_vram_mgr_block_start(struct gpu_buddy_block *block)
|
||||
{
|
||||
return drm_buddy_block_offset(block);
|
||||
return gpu_buddy_block_offset(block);
|
||||
}
|
||||
|
||||
static inline u64 amdgpu_vram_mgr_block_size(struct drm_buddy_block *block)
|
||||
static inline u64 amdgpu_vram_mgr_block_size(struct gpu_buddy_block *block)
|
||||
{
|
||||
return (u64)PAGE_SIZE << drm_buddy_block_order(block);
|
||||
return (u64)PAGE_SIZE << gpu_buddy_block_order(block);
|
||||
}
|
||||
|
||||
static inline bool amdgpu_vram_mgr_is_cleared(struct drm_buddy_block *block)
|
||||
static inline bool amdgpu_vram_mgr_is_cleared(struct gpu_buddy_block *block)
|
||||
{
|
||||
return drm_buddy_block_is_clear(block);
|
||||
return gpu_buddy_block_is_clear(block);
|
||||
}
|
||||
|
||||
static inline struct amdgpu_vram_mgr_resource *
|
||||
@@ -82,8 +82,8 @@ static inline void amdgpu_vram_mgr_set_cleared(struct ttm_resource *res)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *ares = to_amdgpu_vram_mgr_resource(res);
|
||||
|
||||
WARN_ON(ares->flags & DRM_BUDDY_CLEARED);
|
||||
ares->flags |= DRM_BUDDY_CLEARED;
|
||||
WARN_ON(ares->flags & GPU_BUDDY_CLEARED);
|
||||
ares->flags |= GPU_BUDDY_CLEARED;
|
||||
}
|
||||
|
||||
int amdgpu_vram_mgr_query_address_block_info(struct amdgpu_vram_mgr *mgr,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <kunit/test-bug.h>
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/kmemleak.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include <linux/gpu_buddy.h>
|
||||
#include <drm/drm_buddy.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
/**
|
||||
* drm_buddy_block_print - print block information
|
||||
*
|
||||
* @mm: DRM buddy manager
|
||||
* @block: DRM buddy block
|
||||
* @p: DRM printer to use
|
||||
*/
|
||||
void drm_buddy_block_print(struct gpu_buddy *mm,
|
||||
struct gpu_buddy_block *block,
|
||||
struct drm_printer *p)
|
||||
{
|
||||
u64 start = gpu_buddy_block_offset(block);
|
||||
u64 size = gpu_buddy_block_size(mm, block);
|
||||
|
||||
drm_printf(p, "%#018llx-%#018llx: %llu\n", start, start + size, size);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_buddy_block_print);
|
||||
|
||||
/**
|
||||
* drm_buddy_print - print allocator state
|
||||
*
|
||||
* @mm: DRM buddy manager
|
||||
* @p: DRM printer to use
|
||||
*/
|
||||
void drm_buddy_print(struct gpu_buddy *mm, struct drm_printer *p)
|
||||
{
|
||||
int order;
|
||||
|
||||
drm_printf(p, "chunk_size: %lluKiB, total: %lluMiB, free: %lluMiB, clear_free: %lluMiB\n",
|
||||
mm->chunk_size >> 10, mm->size >> 20, mm->avail >> 20, mm->clear_avail >> 20);
|
||||
|
||||
for (order = mm->max_order; order >= 0; order--) {
|
||||
struct gpu_buddy_block *block, *tmp;
|
||||
struct rb_root *root;
|
||||
u64 count = 0, free;
|
||||
unsigned int tree;
|
||||
|
||||
for_each_free_tree(tree) {
|
||||
root = &mm->free_trees[tree][order];
|
||||
|
||||
rbtree_postorder_for_each_entry_safe(block, tmp, root, rb) {
|
||||
BUG_ON(!gpu_buddy_block_is_free(block));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
drm_printf(p, "order-%2d ", order);
|
||||
|
||||
free = count * (mm->chunk_size << order);
|
||||
if (free < SZ_1M)
|
||||
drm_printf(p, "free: %8llu KiB", free >> 10);
|
||||
else
|
||||
drm_printf(p, "free: %8llu MiB", free >> 20);
|
||||
|
||||
drm_printf(p, ", blocks: %llu\n", count);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_buddy_print);
|
||||
|
||||
MODULE_DESCRIPTION("DRM-specific GPU Buddy Allocator Print Helpers");
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
||||
@@ -167,9 +167,9 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res,
|
||||
struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
|
||||
const u64 size = res->size;
|
||||
const u32 max_segment = round_down(UINT_MAX, page_alignment);
|
||||
struct drm_buddy *mm = bman_res->mm;
|
||||
struct gpu_buddy *mm = bman_res->mm;
|
||||
struct list_head *blocks = &bman_res->blocks;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct i915_refct_sgt *rsgt;
|
||||
struct scatterlist *sg;
|
||||
struct sg_table *st;
|
||||
@@ -202,8 +202,8 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res,
|
||||
list_for_each_entry(block, blocks, link) {
|
||||
u64 block_size, offset;
|
||||
|
||||
block_size = min_t(u64, size, drm_buddy_block_size(mm, block));
|
||||
offset = drm_buddy_block_offset(block);
|
||||
block_size = min_t(u64, size, gpu_buddy_block_size(mm, block));
|
||||
offset = gpu_buddy_block_offset(block);
|
||||
|
||||
while (block_size) {
|
||||
u64 len;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/gpu_buddy.h>
|
||||
#include <drm/drm_buddy.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/ttm/ttm_placement.h>
|
||||
#include <drm/ttm/ttm_bo.h>
|
||||
@@ -16,7 +17,7 @@
|
||||
|
||||
struct i915_ttm_buddy_manager {
|
||||
struct ttm_resource_manager manager;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
struct list_head reserved;
|
||||
struct mutex lock;
|
||||
unsigned long visible_size;
|
||||
@@ -38,7 +39,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct i915_ttm_buddy_resource *bman_res;
|
||||
struct drm_buddy *mm = &bman->mm;
|
||||
struct gpu_buddy *mm = &bman->mm;
|
||||
unsigned long n_pages, lpfn;
|
||||
u64 min_page_size;
|
||||
u64 size;
|
||||
@@ -57,13 +58,13 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man,
|
||||
bman_res->mm = mm;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
bman_res->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
|
||||
bman_res->flags |= GPU_BUDDY_TOPDOWN_ALLOCATION;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
|
||||
bman_res->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
bman_res->flags |= GPU_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
|
||||
if (place->fpfn || lpfn != man->size)
|
||||
bman_res->flags |= DRM_BUDDY_RANGE_ALLOCATION;
|
||||
bman_res->flags |= GPU_BUDDY_RANGE_ALLOCATION;
|
||||
|
||||
GEM_BUG_ON(!bman_res->base.size);
|
||||
size = bman_res->base.size;
|
||||
@@ -89,7 +90,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man,
|
||||
goto err_free_res;
|
||||
}
|
||||
|
||||
err = drm_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT,
|
||||
err = gpu_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT,
|
||||
(u64)lpfn << PAGE_SHIFT,
|
||||
(u64)n_pages << PAGE_SHIFT,
|
||||
min_page_size,
|
||||
@@ -101,15 +102,15 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man,
|
||||
if (lpfn <= bman->visible_size) {
|
||||
bman_res->used_visible_size = PFN_UP(bman_res->base.size);
|
||||
} else {
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
list_for_each_entry(block, &bman_res->blocks, link) {
|
||||
unsigned long start =
|
||||
drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
|
||||
if (start < bman->visible_size) {
|
||||
unsigned long end = start +
|
||||
(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
(gpu_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
|
||||
bman_res->used_visible_size +=
|
||||
min(end, bman->visible_size) - start;
|
||||
@@ -126,7 +127,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man,
|
||||
return 0;
|
||||
|
||||
err_free_blocks:
|
||||
drm_buddy_free_list(mm, &bman_res->blocks, 0);
|
||||
gpu_buddy_free_list(mm, &bman_res->blocks, 0);
|
||||
mutex_unlock(&bman->lock);
|
||||
err_free_res:
|
||||
ttm_resource_fini(man, &bman_res->base);
|
||||
@@ -141,7 +142,7 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man,
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
|
||||
mutex_lock(&bman->lock);
|
||||
drm_buddy_free_list(&bman->mm, &bman_res->blocks, 0);
|
||||
gpu_buddy_free_list(&bman->mm, &bman_res->blocks, 0);
|
||||
bman->visible_avail += bman_res->used_visible_size;
|
||||
mutex_unlock(&bman->lock);
|
||||
|
||||
@@ -156,8 +157,8 @@ static bool i915_ttm_buddy_man_intersects(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct drm_buddy *mm = &bman->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &bman->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
if (!place->fpfn && !place->lpfn)
|
||||
return true;
|
||||
@@ -176,9 +177,9 @@ static bool i915_ttm_buddy_man_intersects(struct ttm_resource_manager *man,
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &bman_res->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
(gpu_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
|
||||
if (place->fpfn < lpfn && place->lpfn > fpfn)
|
||||
return true;
|
||||
@@ -194,8 +195,8 @@ static bool i915_ttm_buddy_man_compatible(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct drm_buddy *mm = &bman->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &bman->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
if (!place->fpfn && !place->lpfn)
|
||||
return true;
|
||||
@@ -209,9 +210,9 @@ static bool i915_ttm_buddy_man_compatible(struct ttm_resource_manager *man,
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &bman_res->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
(gpu_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
|
||||
if (fpfn < place->fpfn || lpfn > place->lpfn)
|
||||
return false;
|
||||
@@ -224,7 +225,7 @@ static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man,
|
||||
struct drm_printer *printer)
|
||||
{
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
mutex_lock(&bman->lock);
|
||||
drm_printf(printer, "default_page_size: %lluKiB\n",
|
||||
@@ -293,7 +294,7 @@ int i915_ttm_buddy_man_init(struct ttm_device *bdev,
|
||||
if (!bman)
|
||||
return -ENOMEM;
|
||||
|
||||
err = drm_buddy_init(&bman->mm, size, chunk_size);
|
||||
err = gpu_buddy_init(&bman->mm, size, chunk_size);
|
||||
if (err)
|
||||
goto err_free_bman;
|
||||
|
||||
@@ -333,7 +334,7 @@ int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type)
|
||||
{
|
||||
struct ttm_resource_manager *man = ttm_manager_type(bdev, type);
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct drm_buddy *mm = &bman->mm;
|
||||
struct gpu_buddy *mm = &bman->mm;
|
||||
int ret;
|
||||
|
||||
ttm_resource_manager_set_used(man, false);
|
||||
@@ -345,8 +346,8 @@ int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type)
|
||||
ttm_set_driver_manager(bdev, type, NULL);
|
||||
|
||||
mutex_lock(&bman->lock);
|
||||
drm_buddy_free_list(mm, &bman->reserved, 0);
|
||||
drm_buddy_fini(mm);
|
||||
gpu_buddy_free_list(mm, &bman->reserved, 0);
|
||||
gpu_buddy_fini(mm);
|
||||
bman->visible_avail += bman->visible_reserved;
|
||||
WARN_ON_ONCE(bman->visible_avail != bman->visible_size);
|
||||
mutex_unlock(&bman->lock);
|
||||
@@ -371,15 +372,15 @@ int i915_ttm_buddy_man_reserve(struct ttm_resource_manager *man,
|
||||
u64 start, u64 size)
|
||||
{
|
||||
struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
|
||||
struct drm_buddy *mm = &bman->mm;
|
||||
struct gpu_buddy *mm = &bman->mm;
|
||||
unsigned long fpfn = start >> PAGE_SHIFT;
|
||||
unsigned long flags = 0;
|
||||
int ret;
|
||||
|
||||
flags |= DRM_BUDDY_RANGE_ALLOCATION;
|
||||
flags |= GPU_BUDDY_RANGE_ALLOCATION;
|
||||
|
||||
mutex_lock(&bman->lock);
|
||||
ret = drm_buddy_alloc_blocks(mm, start,
|
||||
ret = gpu_buddy_alloc_blocks(mm, start,
|
||||
start + size,
|
||||
size, mm->chunk_size,
|
||||
&bman->reserved,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
struct ttm_device;
|
||||
struct ttm_resource_manager;
|
||||
struct drm_buddy;
|
||||
struct gpu_buddy;
|
||||
|
||||
/**
|
||||
* struct i915_ttm_buddy_resource
|
||||
@@ -33,7 +33,7 @@ struct i915_ttm_buddy_resource {
|
||||
struct list_head blocks;
|
||||
unsigned long flags;
|
||||
unsigned long used_visible_size;
|
||||
struct drm_buddy *mm;
|
||||
struct gpu_buddy *mm;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <linux/prime_numbers.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include <drm/drm_buddy.h>
|
||||
#include <linux/gpu_buddy.h>
|
||||
|
||||
#include "../i915_selftest.h"
|
||||
|
||||
@@ -371,7 +371,7 @@ static int igt_mock_splintered_region(void *arg)
|
||||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct i915_ttm_buddy_resource *res;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_buddy *mm;
|
||||
struct gpu_buddy *mm;
|
||||
unsigned int expected_order;
|
||||
LIST_HEAD(objects);
|
||||
u64 size;
|
||||
@@ -447,8 +447,8 @@ static int igt_mock_max_segment(void *arg)
|
||||
struct drm_i915_private *i915 = mem->i915;
|
||||
struct i915_ttm_buddy_resource *res;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_buddy_block *block;
|
||||
struct drm_buddy *mm;
|
||||
struct gpu_buddy_block *block;
|
||||
struct gpu_buddy *mm;
|
||||
struct list_head *blocks;
|
||||
struct scatterlist *sg;
|
||||
I915_RND_STATE(prng);
|
||||
@@ -487,8 +487,8 @@ static int igt_mock_max_segment(void *arg)
|
||||
mm = res->mm;
|
||||
size = 0;
|
||||
list_for_each_entry(block, blocks, link) {
|
||||
if (drm_buddy_block_size(mm, block) > size)
|
||||
size = drm_buddy_block_size(mm, block);
|
||||
if (gpu_buddy_block_size(mm, block) > size)
|
||||
size = gpu_buddy_block_size(mm, block);
|
||||
}
|
||||
if (size < max_segment) {
|
||||
pr_err("%s: Failed to create a huge contiguous block [> %u], largest block %lld\n",
|
||||
@@ -527,14 +527,14 @@ static u64 igt_object_mappable_total(struct drm_i915_gem_object *obj)
|
||||
struct intel_memory_region *mr = obj->mm.region;
|
||||
struct i915_ttm_buddy_resource *bman_res =
|
||||
to_ttm_buddy_resource(obj->mm.res);
|
||||
struct drm_buddy *mm = bman_res->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = bman_res->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 total;
|
||||
|
||||
total = 0;
|
||||
list_for_each_entry(block, &bman_res->blocks, link) {
|
||||
u64 start = drm_buddy_block_offset(block);
|
||||
u64 end = start + drm_buddy_block_size(mm, block);
|
||||
u64 start = gpu_buddy_block_offset(block);
|
||||
u64 end = start + gpu_buddy_block_size(mm, block);
|
||||
|
||||
if (start < resource_size(&mr->io))
|
||||
total += min_t(u64, end, resource_size(&mr->io)) - start;
|
||||
|
||||
@@ -251,7 +251,7 @@ static void ttm_bo_validate_basic(struct kunit *test)
|
||||
NULL, &dummy_ttm_bo_destroy);
|
||||
KUNIT_EXPECT_EQ(test, err, 0);
|
||||
|
||||
snd_place = ttm_place_kunit_init(test, snd_mem, DRM_BUDDY_TOPDOWN_ALLOCATION);
|
||||
snd_place = ttm_place_kunit_init(test, snd_mem, GPU_BUDDY_TOPDOWN_ALLOCATION);
|
||||
snd_placement = ttm_placement_kunit_init(test, snd_place, 1);
|
||||
|
||||
err = ttm_bo_validate(bo, snd_placement, &ctx_val);
|
||||
@@ -263,7 +263,7 @@ static void ttm_bo_validate_basic(struct kunit *test)
|
||||
KUNIT_EXPECT_TRUE(test, ttm_tt_is_populated(bo->ttm));
|
||||
KUNIT_EXPECT_EQ(test, bo->resource->mem_type, snd_mem);
|
||||
KUNIT_EXPECT_EQ(test, bo->resource->placement,
|
||||
DRM_BUDDY_TOPDOWN_ALLOCATION);
|
||||
GPU_BUDDY_TOPDOWN_ALLOCATION);
|
||||
|
||||
ttm_bo_fini(bo);
|
||||
ttm_mock_manager_fini(priv->ttm_dev, snd_mem);
|
||||
|
||||
@@ -31,7 +31,7 @@ static int ttm_mock_manager_alloc(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct ttm_mock_manager *manager = to_mock_mgr(man);
|
||||
struct ttm_mock_resource *mock_res;
|
||||
struct drm_buddy *mm = &manager->mm;
|
||||
struct gpu_buddy *mm = &manager->mm;
|
||||
u64 lpfn, fpfn, alloc_size;
|
||||
int err;
|
||||
|
||||
@@ -47,14 +47,14 @@ static int ttm_mock_manager_alloc(struct ttm_resource_manager *man,
|
||||
INIT_LIST_HEAD(&mock_res->blocks);
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
mock_res->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
|
||||
mock_res->flags |= GPU_BUDDY_TOPDOWN_ALLOCATION;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
|
||||
mock_res->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
mock_res->flags |= GPU_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
|
||||
alloc_size = (uint64_t)mock_res->base.size;
|
||||
mutex_lock(&manager->lock);
|
||||
err = drm_buddy_alloc_blocks(mm, fpfn, lpfn, alloc_size,
|
||||
err = gpu_buddy_alloc_blocks(mm, fpfn, lpfn, alloc_size,
|
||||
manager->default_page_size,
|
||||
&mock_res->blocks,
|
||||
mock_res->flags);
|
||||
@@ -67,7 +67,7 @@ static int ttm_mock_manager_alloc(struct ttm_resource_manager *man,
|
||||
return 0;
|
||||
|
||||
error_free_blocks:
|
||||
drm_buddy_free_list(mm, &mock_res->blocks, 0);
|
||||
gpu_buddy_free_list(mm, &mock_res->blocks, 0);
|
||||
ttm_resource_fini(man, &mock_res->base);
|
||||
mutex_unlock(&manager->lock);
|
||||
|
||||
@@ -79,10 +79,10 @@ static void ttm_mock_manager_free(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct ttm_mock_manager *manager = to_mock_mgr(man);
|
||||
struct ttm_mock_resource *mock_res = to_mock_mgr_resource(res);
|
||||
struct drm_buddy *mm = &manager->mm;
|
||||
struct gpu_buddy *mm = &manager->mm;
|
||||
|
||||
mutex_lock(&manager->lock);
|
||||
drm_buddy_free_list(mm, &mock_res->blocks, 0);
|
||||
gpu_buddy_free_list(mm, &mock_res->blocks, 0);
|
||||
mutex_unlock(&manager->lock);
|
||||
|
||||
ttm_resource_fini(man, res);
|
||||
@@ -106,7 +106,7 @@ int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
|
||||
|
||||
mutex_init(&manager->lock);
|
||||
|
||||
err = drm_buddy_init(&manager->mm, size, PAGE_SIZE);
|
||||
err = gpu_buddy_init(&manager->mm, size, PAGE_SIZE);
|
||||
|
||||
if (err) {
|
||||
kfree(manager);
|
||||
@@ -142,7 +142,7 @@ void ttm_mock_manager_fini(struct ttm_device *bdev, u32 mem_type)
|
||||
ttm_resource_manager_set_used(man, false);
|
||||
|
||||
mutex_lock(&mock_man->lock);
|
||||
drm_buddy_fini(&mock_man->mm);
|
||||
gpu_buddy_fini(&mock_man->mm);
|
||||
mutex_unlock(&mock_man->lock);
|
||||
|
||||
ttm_set_driver_manager(bdev, mem_type, NULL);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
struct ttm_mock_manager {
|
||||
struct ttm_resource_manager man;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
u64 default_page_size;
|
||||
/* protects allocations of mock buffer objects */
|
||||
struct mutex lock;
|
||||
|
||||
@@ -58,7 +58,7 @@ struct xe_res_cursor {
|
||||
/** @dma_addr: Current element in a struct drm_pagemap_addr array */
|
||||
const struct drm_pagemap_addr *dma_addr;
|
||||
/** @mm: Buddy allocator for VRAM cursor */
|
||||
struct drm_buddy *mm;
|
||||
struct gpu_buddy *mm;
|
||||
/**
|
||||
* @dma_start: DMA start address for the current segment.
|
||||
* This may be different to @dma_addr.addr since elements in
|
||||
@@ -69,7 +69,7 @@ struct xe_res_cursor {
|
||||
u64 dma_seg_size;
|
||||
};
|
||||
|
||||
static struct drm_buddy *xe_res_get_buddy(struct ttm_resource *res)
|
||||
static struct gpu_buddy *xe_res_get_buddy(struct ttm_resource *res)
|
||||
{
|
||||
struct ttm_resource_manager *mgr;
|
||||
|
||||
@@ -104,30 +104,30 @@ static inline void xe_res_first(struct ttm_resource *res,
|
||||
case XE_PL_STOLEN:
|
||||
case XE_PL_VRAM0:
|
||||
case XE_PL_VRAM1: {
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct list_head *head, *next;
|
||||
struct drm_buddy *mm = xe_res_get_buddy(res);
|
||||
struct gpu_buddy *mm = xe_res_get_buddy(res);
|
||||
|
||||
head = &to_xe_ttm_vram_mgr_resource(res)->blocks;
|
||||
|
||||
block = list_first_entry_or_null(head,
|
||||
struct drm_buddy_block,
|
||||
struct gpu_buddy_block,
|
||||
link);
|
||||
if (!block)
|
||||
goto fallback;
|
||||
|
||||
while (start >= drm_buddy_block_size(mm, block)) {
|
||||
start -= drm_buddy_block_size(mm, block);
|
||||
while (start >= gpu_buddy_block_size(mm, block)) {
|
||||
start -= gpu_buddy_block_size(mm, block);
|
||||
|
||||
next = block->link.next;
|
||||
if (next != head)
|
||||
block = list_entry(next, struct drm_buddy_block,
|
||||
block = list_entry(next, struct gpu_buddy_block,
|
||||
link);
|
||||
}
|
||||
|
||||
cur->mm = mm;
|
||||
cur->start = drm_buddy_block_offset(block) + start;
|
||||
cur->size = min(drm_buddy_block_size(mm, block) - start,
|
||||
cur->start = gpu_buddy_block_offset(block) + start;
|
||||
cur->size = min(gpu_buddy_block_size(mm, block) - start,
|
||||
size);
|
||||
cur->remaining = size;
|
||||
cur->node = block;
|
||||
@@ -259,7 +259,7 @@ static inline void xe_res_first_dma(const struct drm_pagemap_addr *dma_addr,
|
||||
*/
|
||||
static inline void xe_res_next(struct xe_res_cursor *cur, u64 size)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct list_head *next;
|
||||
u64 start;
|
||||
|
||||
@@ -295,18 +295,18 @@ static inline void xe_res_next(struct xe_res_cursor *cur, u64 size)
|
||||
block = cur->node;
|
||||
|
||||
next = block->link.next;
|
||||
block = list_entry(next, struct drm_buddy_block, link);
|
||||
block = list_entry(next, struct gpu_buddy_block, link);
|
||||
|
||||
|
||||
while (start >= drm_buddy_block_size(cur->mm, block)) {
|
||||
start -= drm_buddy_block_size(cur->mm, block);
|
||||
while (start >= gpu_buddy_block_size(cur->mm, block)) {
|
||||
start -= gpu_buddy_block_size(cur->mm, block);
|
||||
|
||||
next = block->link.next;
|
||||
block = list_entry(next, struct drm_buddy_block, link);
|
||||
block = list_entry(next, struct gpu_buddy_block, link);
|
||||
}
|
||||
|
||||
cur->start = drm_buddy_block_offset(block) + start;
|
||||
cur->size = min(drm_buddy_block_size(cur->mm, block) - start,
|
||||
cur->start = gpu_buddy_block_offset(block) + start;
|
||||
cur->size = min(gpu_buddy_block_size(cur->mm, block) - start,
|
||||
cur->remaining);
|
||||
cur->node = block;
|
||||
break;
|
||||
|
||||
@@ -747,7 +747,7 @@ static u64 block_offset_to_pfn(struct drm_pagemap *dpagemap, u64 offset)
|
||||
return PHYS_PFN(offset + xpagemap->hpa_base);
|
||||
}
|
||||
|
||||
static struct drm_buddy *vram_to_buddy(struct xe_vram_region *vram)
|
||||
static struct gpu_buddy *vram_to_buddy(struct xe_vram_region *vram)
|
||||
{
|
||||
return &vram->ttm.mm;
|
||||
}
|
||||
@@ -758,17 +758,17 @@ static int xe_svm_populate_devmem_pfn(struct drm_pagemap_devmem *devmem_allocati
|
||||
struct xe_bo *bo = to_xe_bo(devmem_allocation);
|
||||
struct ttm_resource *res = bo->ttm.resource;
|
||||
struct list_head *blocks = &to_xe_ttm_vram_mgr_resource(res)->blocks;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
int j = 0;
|
||||
|
||||
list_for_each_entry(block, blocks, link) {
|
||||
struct xe_vram_region *vr = block->private;
|
||||
struct drm_buddy *buddy = vram_to_buddy(vr);
|
||||
struct gpu_buddy *buddy = vram_to_buddy(vr);
|
||||
u64 block_pfn = block_offset_to_pfn(devmem_allocation->dpagemap,
|
||||
drm_buddy_block_offset(block));
|
||||
gpu_buddy_block_offset(block));
|
||||
int i;
|
||||
|
||||
for (i = 0; i < drm_buddy_block_size(buddy, block) >> PAGE_SHIFT; ++i)
|
||||
for (i = 0; i < gpu_buddy_block_size(buddy, block) >> PAGE_SHIFT; ++i)
|
||||
pfn[j++] = block_pfn + i;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,7 @@ static int xe_drm_pagemap_populate_mm(struct drm_pagemap *dpagemap,
|
||||
struct dma_fence *pre_migrate_fence = NULL;
|
||||
struct xe_device *xe = vr->xe;
|
||||
struct device *dev = xe->drm.dev;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
struct xe_validation_ctx vctx;
|
||||
struct list_head *blocks;
|
||||
struct drm_exec exec;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_buddy.h>
|
||||
|
||||
#include <drm/ttm/ttm_placement.h>
|
||||
#include <drm/ttm/ttm_range_manager.h>
|
||||
@@ -16,16 +17,16 @@
|
||||
#include "xe_ttm_vram_mgr.h"
|
||||
#include "xe_vram_types.h"
|
||||
|
||||
static inline struct drm_buddy_block *
|
||||
static inline struct gpu_buddy_block *
|
||||
xe_ttm_vram_mgr_first_block(struct list_head *list)
|
||||
{
|
||||
return list_first_entry_or_null(list, struct drm_buddy_block, link);
|
||||
return list_first_entry_or_null(list, struct gpu_buddy_block, link);
|
||||
}
|
||||
|
||||
static inline bool xe_is_vram_mgr_blocks_contiguous(struct drm_buddy *mm,
|
||||
static inline bool xe_is_vram_mgr_blocks_contiguous(struct gpu_buddy *mm,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
u64 start, size;
|
||||
|
||||
block = xe_ttm_vram_mgr_first_block(head);
|
||||
@@ -33,12 +34,12 @@ static inline bool xe_is_vram_mgr_blocks_contiguous(struct drm_buddy *mm,
|
||||
return false;
|
||||
|
||||
while (head != block->link.next) {
|
||||
start = drm_buddy_block_offset(block);
|
||||
size = drm_buddy_block_size(mm, block);
|
||||
start = gpu_buddy_block_offset(block);
|
||||
size = gpu_buddy_block_size(mm, block);
|
||||
|
||||
block = list_entry(block->link.next, struct drm_buddy_block,
|
||||
block = list_entry(block->link.next, struct gpu_buddy_block,
|
||||
link);
|
||||
if (start + size != drm_buddy_block_offset(block))
|
||||
if (start + size != gpu_buddy_block_offset(block))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
{
|
||||
struct xe_ttm_vram_mgr *mgr = to_xe_ttm_vram_mgr(man);
|
||||
struct xe_ttm_vram_mgr_resource *vres;
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
u64 size, min_page_size;
|
||||
unsigned long lpfn;
|
||||
int err;
|
||||
@@ -79,10 +80,10 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
INIT_LIST_HEAD(&vres->blocks);
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_TOPDOWN_ALLOCATION;
|
||||
|
||||
if (place->fpfn || lpfn != man->size >> PAGE_SHIFT)
|
||||
vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
|
||||
vres->flags |= GPU_BUDDY_RANGE_ALLOCATION;
|
||||
|
||||
if (WARN_ON(!vres->base.size)) {
|
||||
err = -EINVAL;
|
||||
@@ -118,27 +119,27 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
lpfn = max_t(unsigned long, place->fpfn + (size >> PAGE_SHIFT), lpfn);
|
||||
}
|
||||
|
||||
err = drm_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT,
|
||||
err = gpu_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT,
|
||||
(u64)lpfn << PAGE_SHIFT, size,
|
||||
min_page_size, &vres->blocks, vres->flags);
|
||||
if (err)
|
||||
goto error_unlock;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
|
||||
if (!drm_buddy_block_trim(mm, NULL, vres->base.size, &vres->blocks))
|
||||
if (!gpu_buddy_block_trim(mm, NULL, vres->base.size, &vres->blocks))
|
||||
size = vres->base.size;
|
||||
}
|
||||
|
||||
if (lpfn <= mgr->visible_size >> PAGE_SHIFT) {
|
||||
vres->used_visible_size = size;
|
||||
} else {
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
list_for_each_entry(block, &vres->blocks, link) {
|
||||
u64 start = drm_buddy_block_offset(block);
|
||||
u64 start = gpu_buddy_block_offset(block);
|
||||
|
||||
if (start < mgr->visible_size) {
|
||||
u64 end = start + drm_buddy_block_size(mm, block);
|
||||
u64 end = start + gpu_buddy_block_size(mm, block);
|
||||
|
||||
vres->used_visible_size +=
|
||||
min(end, mgr->visible_size) - start;
|
||||
@@ -158,11 +159,11 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
* the object.
|
||||
*/
|
||||
if (vres->base.placement & TTM_PL_FLAG_CONTIGUOUS) {
|
||||
struct drm_buddy_block *block = list_first_entry(&vres->blocks,
|
||||
struct gpu_buddy_block *block = list_first_entry(&vres->blocks,
|
||||
typeof(*block),
|
||||
link);
|
||||
|
||||
vres->base.start = drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
vres->base.start = gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
} else {
|
||||
vres->base.start = XE_BO_INVALID_OFFSET;
|
||||
}
|
||||
@@ -184,10 +185,10 @@ static void xe_ttm_vram_mgr_del(struct ttm_resource_manager *man,
|
||||
struct xe_ttm_vram_mgr_resource *vres =
|
||||
to_xe_ttm_vram_mgr_resource(res);
|
||||
struct xe_ttm_vram_mgr *mgr = to_xe_ttm_vram_mgr(man);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
drm_buddy_free_list(mm, &vres->blocks, 0);
|
||||
gpu_buddy_free_list(mm, &vres->blocks, 0);
|
||||
mgr->visible_avail += vres->used_visible_size;
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
@@ -200,7 +201,7 @@ static void xe_ttm_vram_mgr_debug(struct ttm_resource_manager *man,
|
||||
struct drm_printer *printer)
|
||||
{
|
||||
struct xe_ttm_vram_mgr *mgr = to_xe_ttm_vram_mgr(man);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
drm_printf(printer, "default_page_size: %lluKiB\n",
|
||||
@@ -223,8 +224,8 @@ static bool xe_ttm_vram_mgr_intersects(struct ttm_resource_manager *man,
|
||||
struct xe_ttm_vram_mgr *mgr = to_xe_ttm_vram_mgr(man);
|
||||
struct xe_ttm_vram_mgr_resource *vres =
|
||||
to_xe_ttm_vram_mgr_resource(res);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
if (!place->fpfn && !place->lpfn)
|
||||
return true;
|
||||
@@ -234,9 +235,9 @@ static bool xe_ttm_vram_mgr_intersects(struct ttm_resource_manager *man,
|
||||
|
||||
list_for_each_entry(block, &vres->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
(gpu_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
|
||||
if (place->fpfn < lpfn && place->lpfn > fpfn)
|
||||
return true;
|
||||
@@ -253,8 +254,8 @@ static bool xe_ttm_vram_mgr_compatible(struct ttm_resource_manager *man,
|
||||
struct xe_ttm_vram_mgr *mgr = to_xe_ttm_vram_mgr(man);
|
||||
struct xe_ttm_vram_mgr_resource *vres =
|
||||
to_xe_ttm_vram_mgr_resource(res);
|
||||
struct drm_buddy *mm = &mgr->mm;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy *mm = &mgr->mm;
|
||||
struct gpu_buddy_block *block;
|
||||
|
||||
if (!place->fpfn && !place->lpfn)
|
||||
return true;
|
||||
@@ -264,9 +265,9 @@ static bool xe_ttm_vram_mgr_compatible(struct ttm_resource_manager *man,
|
||||
|
||||
list_for_each_entry(block, &vres->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
drm_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
gpu_buddy_block_offset(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(drm_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
(gpu_buddy_block_size(mm, block) >> PAGE_SHIFT);
|
||||
|
||||
if (fpfn < place->fpfn || lpfn > place->lpfn)
|
||||
return false;
|
||||
@@ -296,7 +297,7 @@ static void xe_ttm_vram_mgr_fini(struct drm_device *dev, void *arg)
|
||||
|
||||
WARN_ON_ONCE(mgr->visible_avail != mgr->visible_size);
|
||||
|
||||
drm_buddy_fini(&mgr->mm);
|
||||
gpu_buddy_fini(&mgr->mm);
|
||||
|
||||
ttm_resource_manager_cleanup(&mgr->manager);
|
||||
|
||||
@@ -327,7 +328,7 @@ int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr,
|
||||
mgr->visible_avail = io_size;
|
||||
|
||||
ttm_resource_manager_init(man, &xe->ttm, size);
|
||||
err = drm_buddy_init(&mgr->mm, man->size, default_page_size);
|
||||
err = gpu_buddy_init(&mgr->mm, man->size, default_page_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -375,7 +376,7 @@ int xe_ttm_vram_mgr_alloc_sgt(struct xe_device *xe,
|
||||
if (!*sgt)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Determine the number of DRM_BUDDY blocks to export */
|
||||
/* Determine the number of GPU_BUDDY blocks to export */
|
||||
xe_res_first(res, offset, length, &cursor);
|
||||
while (cursor.remaining) {
|
||||
num_entries++;
|
||||
@@ -392,10 +393,10 @@ int xe_ttm_vram_mgr_alloc_sgt(struct xe_device *xe,
|
||||
sg->length = 0;
|
||||
|
||||
/*
|
||||
* Walk down DRM_BUDDY blocks to populate scatterlist nodes
|
||||
* @note: Use iterator api to get first the DRM_BUDDY block
|
||||
* Walk down GPU_BUDDY blocks to populate scatterlist nodes
|
||||
* @note: Use iterator api to get first the GPU_BUDDY block
|
||||
* and the number of bytes from it. Access the following
|
||||
* DRM_BUDDY block(s) if more buffer needs to exported
|
||||
* GPU_BUDDY block(s) if more buffer needs to exported
|
||||
*/
|
||||
xe_res_first(res, offset, length, &cursor);
|
||||
for_each_sgtable_sg((*sgt), sg, i) {
|
||||
|
||||
@@ -18,7 +18,7 @@ struct xe_ttm_vram_mgr {
|
||||
/** @manager: Base TTM resource manager */
|
||||
struct ttm_resource_manager manager;
|
||||
/** @mm: DRM buddy allocator which manages the VRAM */
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
/** @visible_size: Proped size of the CPU visible portion */
|
||||
u64 visible_size;
|
||||
/** @visible_avail: CPU visible portion still unallocated */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
gpu_buddy_tests-y = gpu_buddy_test.o gpu_random.o
|
||||
obj-$(CONFIG_DRM_KUNIT_TEST) += gpu_buddy_tests.o
|
||||
obj-$(CONFIG_GPU_BUDDY_KUNIT_TEST) += gpu_buddy_tests.o
|
||||
|
||||
+206
-206
@@ -21,9 +21,9 @@ static inline u64 get_size(int order, u64 chunk_size)
|
||||
return (1 << order) * chunk_size;
|
||||
}
|
||||
|
||||
static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
static void gpu_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
{
|
||||
struct drm_buddy_block *block, *tmp;
|
||||
struct gpu_buddy_block *block, *tmp;
|
||||
int num_blocks, i, ret, count = 0;
|
||||
LIST_HEAD(allocated_blocks);
|
||||
unsigned long elapsed_ms;
|
||||
@@ -32,7 +32,7 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
LIST_HEAD(clear_list);
|
||||
LIST_HEAD(dirty_list);
|
||||
LIST_HEAD(free_list);
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
u64 mm_size = SZ_4G;
|
||||
ktime_t start, end;
|
||||
|
||||
@@ -47,7 +47,7 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
* quickly the allocator can satisfy larger, aligned requests from a pool of
|
||||
* highly fragmented space.
|
||||
*/
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, SZ_4K),
|
||||
"buddy_init failed\n");
|
||||
|
||||
num_blocks = mm_size / SZ_64K;
|
||||
@@ -55,7 +55,7 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
start = ktime_get();
|
||||
/* Allocate with maximum fragmentation - 8K blocks with 64K alignment */
|
||||
for (i = 0; i < num_blocks; i++)
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, SZ_8K, SZ_64K,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size, SZ_8K, SZ_64K,
|
||||
&allocated_blocks, 0),
|
||||
"buddy_alloc hit an error size=%u\n", SZ_8K);
|
||||
|
||||
@@ -68,21 +68,21 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
}
|
||||
|
||||
/* Free with different flags to ensure no coalescing */
|
||||
drm_buddy_free_list(&mm, &clear_list, DRM_BUDDY_CLEARED);
|
||||
drm_buddy_free_list(&mm, &dirty_list, 0);
|
||||
gpu_buddy_free_list(&mm, &clear_list, GPU_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &dirty_list, 0);
|
||||
|
||||
for (i = 0; i < num_blocks; i++)
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, SZ_64K, SZ_64K,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size, SZ_64K, SZ_64K,
|
||||
&test_blocks, 0),
|
||||
"buddy_alloc hit an error size=%u\n", SZ_64K);
|
||||
drm_buddy_free_list(&mm, &test_blocks, 0);
|
||||
gpu_buddy_free_list(&mm, &test_blocks, 0);
|
||||
|
||||
end = ktime_get();
|
||||
elapsed_ms = ktime_to_ms(ktime_sub(end, start));
|
||||
|
||||
kunit_info(test, "Fragmented allocation took %lu ms\n", elapsed_ms);
|
||||
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_fini(&mm);
|
||||
|
||||
/*
|
||||
* Reverse free order under fragmentation
|
||||
@@ -96,13 +96,13 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
* deallocation occurs in the opposite order of allocation, exposing the
|
||||
* cost difference between a linear freelist scan and an ordered tree lookup.
|
||||
*/
|
||||
ret = drm_buddy_init(&mm, mm_size, SZ_4K);
|
||||
ret = gpu_buddy_init(&mm, mm_size, SZ_4K);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
start = ktime_get();
|
||||
/* Allocate maximum fragmentation */
|
||||
for (i = 0; i < num_blocks; i++)
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, SZ_8K, SZ_64K,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size, SZ_8K, SZ_64K,
|
||||
&allocated_blocks, 0),
|
||||
"buddy_alloc hit an error size=%u\n", SZ_8K);
|
||||
|
||||
@@ -111,28 +111,28 @@ static void drm_test_buddy_fragmentation_performance(struct kunit *test)
|
||||
list_move_tail(&block->link, &free_list);
|
||||
count++;
|
||||
}
|
||||
drm_buddy_free_list(&mm, &free_list, DRM_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &free_list, GPU_BUDDY_CLEARED);
|
||||
|
||||
list_for_each_entry_safe_reverse(block, tmp, &allocated_blocks, link)
|
||||
list_move(&block->link, &reverse_list);
|
||||
drm_buddy_free_list(&mm, &reverse_list, DRM_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &reverse_list, GPU_BUDDY_CLEARED);
|
||||
|
||||
end = ktime_get();
|
||||
elapsed_ms = ktime_to_ms(ktime_sub(end, start));
|
||||
|
||||
kunit_info(test, "Reverse-ordered free took %lu ms\n", elapsed_ms);
|
||||
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
{
|
||||
u32 mm_size, size, ps, bias_size, bias_start, bias_end, bias_rem;
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
GPU_RND_STATE(prng, random_seed);
|
||||
unsigned int i, count, *order;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
unsigned long flags;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
LIST_HEAD(allocated);
|
||||
|
||||
bias_size = SZ_1M;
|
||||
@@ -142,11 +142,11 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
|
||||
kunit_info(test, "mm_size=%u, ps=%u\n", mm_size, ps);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, ps),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, ps),
|
||||
"buddy_init failed\n");
|
||||
|
||||
count = mm_size / bias_size;
|
||||
order = drm_random_order(count, &prng);
|
||||
order = gpu_random_order(count, &prng);
|
||||
KUNIT_EXPECT_TRUE(test, order);
|
||||
|
||||
/*
|
||||
@@ -166,79 +166,79 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
|
||||
/* internal round_up too big */
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, bias_size + ps, bias_size,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, bias_size, bias_size);
|
||||
|
||||
/* size too big */
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, bias_size + ps, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, bias_size + ps, ps);
|
||||
|
||||
/* bias range too small for size */
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start + ps,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start + ps,
|
||||
bias_end, bias_size, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start + ps, bias_end, bias_size, ps);
|
||||
|
||||
/* bias misaligned */
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start + ps,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start + ps,
|
||||
bias_end - ps,
|
||||
bias_size >> 1, bias_size >> 1,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc h didn't fail with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start + ps, bias_end - ps, bias_size >> 1, bias_size >> 1);
|
||||
|
||||
/* single big page */
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, bias_size, bias_size,
|
||||
&tmp,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc i failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, bias_size, bias_size);
|
||||
drm_buddy_free_list(&mm, &tmp, 0);
|
||||
gpu_buddy_free_list(&mm, &tmp, 0);
|
||||
|
||||
/* single page with internal round_up */
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, ps, bias_size,
|
||||
&tmp,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, ps, bias_size);
|
||||
drm_buddy_free_list(&mm, &tmp, 0);
|
||||
gpu_buddy_free_list(&mm, &tmp, 0);
|
||||
|
||||
/* random size within */
|
||||
size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
|
||||
if (size)
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, size, ps,
|
||||
&tmp,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, size, ps);
|
||||
|
||||
bias_rem -= size;
|
||||
/* too big for current avail */
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, bias_rem + ps, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, bias_rem + ps, ps);
|
||||
|
||||
@@ -248,10 +248,10 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
size = max(size, ps);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, size, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, size, ps);
|
||||
/*
|
||||
@@ -259,15 +259,15 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
* unallocated, and ideally not always on the bias
|
||||
* boundaries.
|
||||
*/
|
||||
drm_buddy_free_list(&mm, &tmp, 0);
|
||||
gpu_buddy_free_list(&mm, &tmp, 0);
|
||||
} else {
|
||||
list_splice_tail(&tmp, &allocated);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(order);
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
|
||||
/*
|
||||
* Something more free-form. Idea is to pick a random starting bias
|
||||
@@ -278,7 +278,7 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
* allocated nodes in the middle of the address space.
|
||||
*/
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, ps),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, ps),
|
||||
"buddy_init failed\n");
|
||||
|
||||
bias_start = round_up(prandom_u32_state(&prng) % (mm_size - ps), ps);
|
||||
@@ -290,10 +290,10 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
u32 size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, size, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
|
||||
bias_start, bias_end, size, ps);
|
||||
bias_rem -= size;
|
||||
@@ -319,24 +319,24 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
KUNIT_ASSERT_EQ(test, bias_start, 0);
|
||||
KUNIT_ASSERT_EQ(test, bias_end, mm_size);
|
||||
KUNIT_ASSERT_TRUE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start, bias_end,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start, bias_end,
|
||||
ps, ps,
|
||||
&allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc passed with bias(%x-%x), size=%u\n",
|
||||
bias_start, bias_end, ps);
|
||||
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
|
||||
/*
|
||||
* Allocate cleared blocks in the bias range when the DRM buddy's clear avail is
|
||||
* Allocate cleared blocks in the bias range when the GPU buddy's clear avail is
|
||||
* zero. This will validate the bias range allocation in scenarios like system boot
|
||||
* when no cleared blocks are available and exercise the fallback path too. The resulting
|
||||
* blocks should always be dirty.
|
||||
*/
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, ps),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, ps),
|
||||
"buddy_init failed\n");
|
||||
|
||||
bias_start = round_up(prandom_u32_state(&prng) % (mm_size - ps), ps);
|
||||
@@ -344,11 +344,11 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
bias_end = max(bias_end, bias_start + ps);
|
||||
bias_rem = bias_end - bias_start;
|
||||
|
||||
flags = DRM_BUDDY_CLEAR_ALLOCATION | DRM_BUDDY_RANGE_ALLOCATION;
|
||||
flags = GPU_BUDDY_CLEAR_ALLOCATION | GPU_BUDDY_RANGE_ALLOCATION;
|
||||
size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, bias_start,
|
||||
gpu_buddy_alloc_blocks(&mm, bias_start,
|
||||
bias_end, size, ps,
|
||||
&allocated,
|
||||
flags),
|
||||
@@ -356,27 +356,27 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
|
||||
bias_start, bias_end, size, ps);
|
||||
|
||||
list_for_each_entry(block, &allocated, link)
|
||||
KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), false);
|
||||
KUNIT_EXPECT_EQ(test, gpu_buddy_block_is_clear(block), false);
|
||||
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_clear(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_clear(struct kunit *test)
|
||||
{
|
||||
unsigned long n_pages, total, i = 0;
|
||||
const unsigned long ps = SZ_4K;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
const int max_order = 12;
|
||||
LIST_HEAD(allocated);
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
unsigned int order;
|
||||
u32 mm_size, size;
|
||||
LIST_HEAD(dirty);
|
||||
LIST_HEAD(clean);
|
||||
|
||||
mm_size = SZ_4K << max_order;
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
|
||||
|
||||
@@ -389,11 +389,11 @@ static void drm_test_buddy_alloc_clear(struct kunit *test)
|
||||
* is indeed all dirty pages and vice versa. Free it all again,
|
||||
* keeping the dirty/clear status.
|
||||
*/
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
5 * ps, ps, &allocated,
|
||||
DRM_BUDDY_TOPDOWN_ALLOCATION),
|
||||
GPU_BUDDY_TOPDOWN_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 5 * ps);
|
||||
drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &allocated, GPU_BUDDY_CLEARED);
|
||||
|
||||
n_pages = 10;
|
||||
do {
|
||||
@@ -406,37 +406,37 @@ static void drm_test_buddy_alloc_clear(struct kunit *test)
|
||||
flags = 0;
|
||||
} else {
|
||||
list = &clean;
|
||||
flags = DRM_BUDDY_CLEAR_ALLOCATION;
|
||||
flags = GPU_BUDDY_CLEAR_ALLOCATION;
|
||||
}
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
ps, ps, list,
|
||||
flags),
|
||||
"buddy_alloc hit an error size=%lu\n", ps);
|
||||
} while (++i < n_pages);
|
||||
|
||||
list_for_each_entry(block, &clean, link)
|
||||
KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), true);
|
||||
KUNIT_EXPECT_EQ(test, gpu_buddy_block_is_clear(block), true);
|
||||
|
||||
list_for_each_entry(block, &dirty, link)
|
||||
KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), false);
|
||||
KUNIT_EXPECT_EQ(test, gpu_buddy_block_is_clear(block), false);
|
||||
|
||||
drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &clean, GPU_BUDDY_CLEARED);
|
||||
|
||||
/*
|
||||
* Trying to go over the clear limit for some allocation.
|
||||
* The allocation should never fail with reasonable page-size.
|
||||
*/
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
10 * ps, ps, &clean,
|
||||
DRM_BUDDY_CLEAR_ALLOCATION),
|
||||
GPU_BUDDY_CLEAR_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 10 * ps);
|
||||
|
||||
drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
|
||||
drm_buddy_free_list(&mm, &dirty, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &clean, GPU_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &dirty, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
|
||||
|
||||
/*
|
||||
* Create a new mm. Intentionally fragment the address space by creating
|
||||
@@ -458,34 +458,34 @@ static void drm_test_buddy_alloc_clear(struct kunit *test)
|
||||
else
|
||||
list = &clean;
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
ps, ps, list, 0),
|
||||
"buddy_alloc hit an error size=%lu\n", ps);
|
||||
} while (++i < n_pages);
|
||||
|
||||
drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
|
||||
drm_buddy_free_list(&mm, &dirty, 0);
|
||||
gpu_buddy_free_list(&mm, &clean, GPU_BUDDY_CLEARED);
|
||||
gpu_buddy_free_list(&mm, &dirty, 0);
|
||||
|
||||
order = 1;
|
||||
do {
|
||||
size = SZ_4K << order;
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
size, size, &allocated,
|
||||
DRM_BUDDY_CLEAR_ALLOCATION),
|
||||
GPU_BUDDY_CLEAR_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%u\n", size);
|
||||
total = 0;
|
||||
list_for_each_entry(block, &allocated, link) {
|
||||
if (size != mm_size)
|
||||
KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), false);
|
||||
total += drm_buddy_block_size(&mm, block);
|
||||
KUNIT_EXPECT_EQ(test, gpu_buddy_block_is_clear(block), false);
|
||||
total += gpu_buddy_block_size(&mm, block);
|
||||
}
|
||||
KUNIT_EXPECT_EQ(test, total, size);
|
||||
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
} while (++order <= max_order);
|
||||
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_fini(&mm);
|
||||
|
||||
/*
|
||||
* Create a new mm with a non power-of-two size. Allocate a random size from each
|
||||
@@ -494,44 +494,44 @@ static void drm_test_buddy_alloc_clear(struct kunit *test)
|
||||
*/
|
||||
mm_size = (SZ_4K << max_order) + (SZ_4K << (max_order - 2));
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
|
||||
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order,
|
||||
4 * ps, ps, &allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 4 * ps);
|
||||
drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order,
|
||||
gpu_buddy_free_list(&mm, &allocated, GPU_BUDDY_CLEARED);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order,
|
||||
2 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CLEAR_ALLOCATION),
|
||||
GPU_BUDDY_CLEAR_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 2 * ps);
|
||||
drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, SZ_4K << max_order, mm_size,
|
||||
gpu_buddy_free_list(&mm, &allocated, GPU_BUDDY_CLEARED);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, SZ_4K << max_order, mm_size,
|
||||
ps, ps, &allocated,
|
||||
DRM_BUDDY_RANGE_ALLOCATION),
|
||||
GPU_BUDDY_RANGE_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", ps);
|
||||
drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, GPU_BUDDY_CLEARED);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_contiguous(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_contiguous(struct kunit *test)
|
||||
{
|
||||
const unsigned long ps = SZ_4K, mm_size = 16 * 3 * SZ_4K;
|
||||
unsigned long i, n_pages, total;
|
||||
struct drm_buddy_block *block;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy_block *block;
|
||||
struct gpu_buddy mm;
|
||||
LIST_HEAD(left);
|
||||
LIST_HEAD(middle);
|
||||
LIST_HEAD(right);
|
||||
LIST_HEAD(allocated);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
|
||||
|
||||
/*
|
||||
* Idea is to fragment the address space by alternating block
|
||||
* allocations between three different lists; one for left, middle and
|
||||
* right. We can then free a list to simulate fragmentation. In
|
||||
* particular we want to exercise the DRM_BUDDY_CONTIGUOUS_ALLOCATION,
|
||||
* particular we want to exercise the GPU_BUDDY_CONTIGUOUS_ALLOCATION,
|
||||
* including the try_harder path.
|
||||
*/
|
||||
|
||||
@@ -548,66 +548,66 @@ static void drm_test_buddy_alloc_contiguous(struct kunit *test)
|
||||
else
|
||||
list = &right;
|
||||
KUNIT_ASSERT_FALSE_MSG(test,
|
||||
drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
ps, ps, list, 0),
|
||||
"buddy_alloc hit an error size=%lu\n",
|
||||
ps);
|
||||
} while (++i < n_pages);
|
||||
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
3 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc didn't error size=%lu\n", 3 * ps);
|
||||
|
||||
drm_buddy_free_list(&mm, &middle, 0);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
gpu_buddy_free_list(&mm, &middle, 0);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
3 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc didn't error size=%lu\n", 3 * ps);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
2 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc didn't error size=%lu\n", 2 * ps);
|
||||
|
||||
drm_buddy_free_list(&mm, &right, 0);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
gpu_buddy_free_list(&mm, &right, 0);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
3 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc didn't error size=%lu\n", 3 * ps);
|
||||
/*
|
||||
* At this point we should have enough contiguous space for 2 blocks,
|
||||
* however they are never buddies (since we freed middle and right) so
|
||||
* will require the try_harder logic to find them.
|
||||
*/
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
2 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 2 * ps);
|
||||
|
||||
drm_buddy_free_list(&mm, &left, 0);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
gpu_buddy_free_list(&mm, &left, 0);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size,
|
||||
3 * ps, ps, &allocated,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%lu\n", 3 * ps);
|
||||
|
||||
total = 0;
|
||||
list_for_each_entry(block, &allocated, link)
|
||||
total += drm_buddy_block_size(&mm, block);
|
||||
total += gpu_buddy_block_size(&mm, block);
|
||||
|
||||
KUNIT_ASSERT_EQ(test, total, ps * 2 + ps * 3);
|
||||
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_pathological(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_pathological(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
const int max_order = 3;
|
||||
unsigned long flags = 0;
|
||||
int order, top;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
LIST_HEAD(blocks);
|
||||
LIST_HEAD(holes);
|
||||
LIST_HEAD(tmp);
|
||||
@@ -620,7 +620,7 @@ static void drm_test_buddy_alloc_pathological(struct kunit *test)
|
||||
*/
|
||||
|
||||
mm_size = SZ_4K << max_order;
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, SZ_4K),
|
||||
"buddy_init failed\n");
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
|
||||
@@ -630,18 +630,18 @@ static void drm_test_buddy_alloc_pathological(struct kunit *test)
|
||||
block = list_first_entry_or_null(&blocks, typeof(*block), link);
|
||||
if (block) {
|
||||
list_del(&block->link);
|
||||
drm_buddy_free_block(&mm, block);
|
||||
gpu_buddy_free_block(&mm, block);
|
||||
}
|
||||
|
||||
for (order = top; order--;) {
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start,
|
||||
mm_size, size, size,
|
||||
&tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM with order=%d, top=%d\n",
|
||||
order, top);
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_move_tail(&block->link, &blocks);
|
||||
@@ -649,45 +649,45 @@ static void drm_test_buddy_alloc_pathological(struct kunit *test)
|
||||
|
||||
/* There should be one final page for this sub-allocation */
|
||||
size = get_size(0, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM for hole\n");
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_move_tail(&block->link, &holes);
|
||||
|
||||
size = get_size(top, mm.chunk_size);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!",
|
||||
top, max_order);
|
||||
}
|
||||
|
||||
drm_buddy_free_list(&mm, &holes, 0);
|
||||
gpu_buddy_free_list(&mm, &holes, 0);
|
||||
|
||||
/* Nothing larger than blocks of chunk_size now available */
|
||||
for (order = 1; order <= max_order; order++) {
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc unexpectedly succeeded at order %d, it should be full!",
|
||||
order);
|
||||
}
|
||||
|
||||
list_splice_tail(&holes, &blocks);
|
||||
drm_buddy_free_list(&mm, &blocks, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &blocks, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block, *bn;
|
||||
struct gpu_buddy_block *block, *bn;
|
||||
const unsigned int max_order = 16;
|
||||
unsigned long flags = 0;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
unsigned int order;
|
||||
LIST_HEAD(blocks);
|
||||
LIST_HEAD(tmp);
|
||||
@@ -699,19 +699,19 @@ static void drm_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
*/
|
||||
|
||||
mm_size = SZ_4K << max_order;
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, SZ_4K),
|
||||
"buddy_init failed\n");
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
|
||||
|
||||
for (order = 0; order < max_order; order++) {
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM with order=%d\n",
|
||||
order);
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_move_tail(&block->link, &blocks);
|
||||
@@ -719,11 +719,11 @@ static void drm_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
|
||||
/* And now the last remaining block available */
|
||||
size = get_size(0, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM on final alloc\n");
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_move_tail(&block->link, &blocks);
|
||||
@@ -731,58 +731,58 @@ static void drm_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
/* Should be completely full! */
|
||||
for (order = max_order; order--;) {
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc unexpectedly succeeded, it should be full!");
|
||||
}
|
||||
|
||||
block = list_last_entry(&blocks, typeof(*block), link);
|
||||
list_del(&block->link);
|
||||
drm_buddy_free_block(&mm, block);
|
||||
gpu_buddy_free_block(&mm, block);
|
||||
|
||||
/* As we free in increasing size, we make available larger blocks */
|
||||
order = 1;
|
||||
list_for_each_entry_safe(block, bn, &blocks, link) {
|
||||
list_del(&block->link);
|
||||
drm_buddy_free_block(&mm, block);
|
||||
gpu_buddy_free_block(&mm, block);
|
||||
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM with order=%d\n",
|
||||
order);
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_del(&block->link);
|
||||
drm_buddy_free_block(&mm, block);
|
||||
gpu_buddy_free_block(&mm, block);
|
||||
order++;
|
||||
}
|
||||
|
||||
/* To confirm, now the whole mm should be available */
|
||||
size = get_size(max_order, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc (realloc) hit -ENOMEM with order=%d\n",
|
||||
max_order);
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_del(&block->link);
|
||||
drm_buddy_free_block(&mm, block);
|
||||
drm_buddy_free_list(&mm, &blocks, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_block(&mm, block);
|
||||
gpu_buddy_free_list(&mm, &blocks, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_optimistic(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_optimistic(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
unsigned long flags = 0;
|
||||
const int max_order = 16;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
LIST_HEAD(blocks);
|
||||
LIST_HEAD(tmp);
|
||||
int order;
|
||||
@@ -794,19 +794,19 @@ static void drm_test_buddy_alloc_optimistic(struct kunit *test)
|
||||
|
||||
mm_size = SZ_4K * ((1 << (max_order + 1)) - 1);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, SZ_4K),
|
||||
"buddy_init failed\n");
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
|
||||
|
||||
for (order = 0; order <= max_order; order++) {
|
||||
size = get_size(order, mm.chunk_size);
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc hit -ENOMEM with order=%d\n",
|
||||
order);
|
||||
|
||||
block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&tmp, struct gpu_buddy_block, link);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n");
|
||||
|
||||
list_move_tail(&block->link, &blocks);
|
||||
@@ -814,115 +814,115 @@ static void drm_test_buddy_alloc_optimistic(struct kunit *test)
|
||||
|
||||
/* Should be completely full! */
|
||||
size = get_size(0, mm.chunk_size);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
KUNIT_ASSERT_TRUE_MSG(test, gpu_buddy_alloc_blocks(&mm, start, mm_size,
|
||||
size, size, &tmp, flags),
|
||||
"buddy_alloc unexpectedly succeeded, it should be full!");
|
||||
|
||||
drm_buddy_free_list(&mm, &blocks, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &blocks, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_limit(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_limit(struct kunit *test)
|
||||
{
|
||||
u64 size = U64_MAX, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
struct gpu_buddy_block *block;
|
||||
unsigned long flags = 0;
|
||||
LIST_HEAD(allocated);
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, size, SZ_4K));
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, size, SZ_4K));
|
||||
|
||||
KUNIT_EXPECT_EQ_MSG(test, mm.max_order, DRM_BUDDY_MAX_ORDER,
|
||||
KUNIT_EXPECT_EQ_MSG(test, mm.max_order, GPU_BUDDY_MAX_ORDER,
|
||||
"mm.max_order(%d) != %d\n", mm.max_order,
|
||||
DRM_BUDDY_MAX_ORDER);
|
||||
GPU_BUDDY_MAX_ORDER);
|
||||
|
||||
size = mm.chunk_size << mm.max_order;
|
||||
KUNIT_EXPECT_FALSE(test, drm_buddy_alloc_blocks(&mm, start, size, size,
|
||||
KUNIT_EXPECT_FALSE(test, gpu_buddy_alloc_blocks(&mm, start, size, size,
|
||||
mm.chunk_size, &allocated, flags));
|
||||
|
||||
block = list_first_entry_or_null(&allocated, struct drm_buddy_block, link);
|
||||
block = list_first_entry_or_null(&allocated, struct gpu_buddy_block, link);
|
||||
KUNIT_EXPECT_TRUE(test, block);
|
||||
|
||||
KUNIT_EXPECT_EQ_MSG(test, drm_buddy_block_order(block), mm.max_order,
|
||||
KUNIT_EXPECT_EQ_MSG(test, gpu_buddy_block_order(block), mm.max_order,
|
||||
"block order(%d) != %d\n",
|
||||
drm_buddy_block_order(block), mm.max_order);
|
||||
gpu_buddy_block_order(block), mm.max_order);
|
||||
|
||||
KUNIT_EXPECT_EQ_MSG(test, drm_buddy_block_size(&mm, block),
|
||||
KUNIT_EXPECT_EQ_MSG(test, gpu_buddy_block_size(&mm, block),
|
||||
BIT_ULL(mm.max_order) * mm.chunk_size,
|
||||
"block size(%llu) != %llu\n",
|
||||
drm_buddy_block_size(&mm, block),
|
||||
gpu_buddy_block_size(&mm, block),
|
||||
BIT_ULL(mm.max_order) * mm.chunk_size);
|
||||
|
||||
drm_buddy_free_list(&mm, &allocated, 0);
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_free_list(&mm, &allocated, 0);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void drm_test_buddy_alloc_exceeds_max_order(struct kunit *test)
|
||||
static void gpu_test_buddy_alloc_exceeds_max_order(struct kunit *test)
|
||||
{
|
||||
u64 mm_size = SZ_8G + SZ_2G, size = SZ_8G + SZ_1G, min_block_size = SZ_8G;
|
||||
struct drm_buddy mm;
|
||||
struct gpu_buddy mm;
|
||||
LIST_HEAD(blocks);
|
||||
int err;
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_init(&mm, mm_size, SZ_4K),
|
||||
"buddy_init failed\n");
|
||||
|
||||
/* CONTIGUOUS allocation should succeed via try_harder fallback */
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, size,
|
||||
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, mm_size, size,
|
||||
SZ_4K, &blocks,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION),
|
||||
"buddy_alloc hit an error size=%llu\n", size);
|
||||
drm_buddy_free_list(&mm, &blocks, 0);
|
||||
gpu_buddy_free_list(&mm, &blocks, 0);
|
||||
|
||||
/* Non-CONTIGUOUS with large min_block_size should return -EINVAL */
|
||||
err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks, 0);
|
||||
err = gpu_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks, 0);
|
||||
KUNIT_EXPECT_EQ(test, err, -EINVAL);
|
||||
|
||||
/* Non-CONTIGUOUS + RANGE with large min_block_size should return -EINVAL */
|
||||
err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks,
|
||||
DRM_BUDDY_RANGE_ALLOCATION);
|
||||
err = gpu_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks,
|
||||
GPU_BUDDY_RANGE_ALLOCATION);
|
||||
KUNIT_EXPECT_EQ(test, err, -EINVAL);
|
||||
|
||||
/* CONTIGUOUS + RANGE should return -EINVAL (no try_harder for RANGE) */
|
||||
err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, SZ_4K, &blocks,
|
||||
DRM_BUDDY_CONTIGUOUS_ALLOCATION | DRM_BUDDY_RANGE_ALLOCATION);
|
||||
err = gpu_buddy_alloc_blocks(&mm, 0, mm_size, size, SZ_4K, &blocks,
|
||||
GPU_BUDDY_CONTIGUOUS_ALLOCATION | GPU_BUDDY_RANGE_ALLOCATION);
|
||||
KUNIT_EXPECT_EQ(test, err, -EINVAL);
|
||||
|
||||
drm_buddy_fini(&mm);
|
||||
gpu_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static int drm_buddy_suite_init(struct kunit_suite *suite)
|
||||
static int gpu_buddy_suite_init(struct kunit_suite *suite)
|
||||
{
|
||||
while (!random_seed)
|
||||
random_seed = get_random_u32();
|
||||
|
||||
kunit_info(suite, "Testing DRM buddy manager, with random_seed=0x%x\n",
|
||||
kunit_info(suite, "Testing GPU buddy manager, with random_seed=0x%x\n",
|
||||
random_seed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kunit_case drm_buddy_tests[] = {
|
||||
KUNIT_CASE(drm_test_buddy_alloc_limit),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_optimistic),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_pessimistic),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_pathological),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_contiguous),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_clear),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_range_bias),
|
||||
KUNIT_CASE(drm_test_buddy_fragmentation_performance),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_exceeds_max_order),
|
||||
static struct kunit_case gpu_buddy_tests[] = {
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_limit),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_optimistic),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_pessimistic),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_pathological),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_contiguous),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_clear),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_range_bias),
|
||||
KUNIT_CASE(gpu_test_buddy_fragmentation_performance),
|
||||
KUNIT_CASE(gpu_test_buddy_alloc_exceeds_max_order),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_buddy_test_suite = {
|
||||
.name = "drm_buddy",
|
||||
.suite_init = drm_buddy_suite_init,
|
||||
.test_cases = drm_buddy_tests,
|
||||
static struct kunit_suite gpu_buddy_test_suite = {
|
||||
.name = "gpu_buddy",
|
||||
.suite_init = gpu_buddy_suite_init,
|
||||
.test_cases = gpu_buddy_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_buddy_test_suite);
|
||||
kunit_test_suite(gpu_buddy_test_suite);
|
||||
|
||||
MODULE_AUTHOR("Intel Corporation");
|
||||
MODULE_DESCRIPTION("Kunit test for drm_buddy functions");
|
||||
MODULE_DESCRIPTION("Kunit test for gpu_buddy functions");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -8,26 +8,26 @@
|
||||
|
||||
#include "gpu_random.h"
|
||||
|
||||
u32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
|
||||
u32 gpu_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
|
||||
{
|
||||
return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_prandom_u32_max_state);
|
||||
EXPORT_SYMBOL(gpu_prandom_u32_max_state);
|
||||
|
||||
void drm_random_reorder(unsigned int *order, unsigned int count,
|
||||
void gpu_random_reorder(unsigned int *order, unsigned int count,
|
||||
struct rnd_state *state)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
|
||||
j = drm_prandom_u32_max_state(count, state);
|
||||
j = gpu_prandom_u32_max_state(count, state);
|
||||
swap(order[i], order[j]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_random_reorder);
|
||||
EXPORT_SYMBOL(gpu_random_reorder);
|
||||
|
||||
unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
|
||||
unsigned int *gpu_random_order(unsigned int count, struct rnd_state *state)
|
||||
{
|
||||
unsigned int *order, i;
|
||||
|
||||
@@ -38,7 +38,7 @@ unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
|
||||
for (i = 0; i < count; i++)
|
||||
order[i] = i;
|
||||
|
||||
drm_random_reorder(order, count, state);
|
||||
gpu_random_reorder(order, count, state);
|
||||
return order;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_random_order);
|
||||
EXPORT_SYMBOL(gpu_random_order);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DRM_RANDOM_H__
|
||||
#define __DRM_RANDOM_H__
|
||||
#ifndef __GPU_RANDOM_H__
|
||||
#define __GPU_RANDOM_H__
|
||||
|
||||
/* This is a temporary home for a couple of utility functions that should
|
||||
* be transposed to lib/ at the earliest convenience.
|
||||
@@ -8,21 +8,21 @@
|
||||
|
||||
#include <linux/prandom.h>
|
||||
|
||||
#define DRM_RND_STATE_INITIALIZER(seed__) ({ \
|
||||
#define GPU_RND_STATE_INITIALIZER(seed__) ({ \
|
||||
struct rnd_state state__; \
|
||||
prandom_seed_state(&state__, (seed__)); \
|
||||
state__; \
|
||||
})
|
||||
|
||||
#define DRM_RND_STATE(name__, seed__) \
|
||||
struct rnd_state name__ = DRM_RND_STATE_INITIALIZER(seed__)
|
||||
#define GPU_RND_STATE(name__, seed__) \
|
||||
struct rnd_state name__ = GPU_RND_STATE_INITIALIZER(seed__)
|
||||
|
||||
unsigned int *drm_random_order(unsigned int count,
|
||||
unsigned int *gpu_random_order(unsigned int count,
|
||||
struct rnd_state *state);
|
||||
void drm_random_reorder(unsigned int *order,
|
||||
void gpu_random_reorder(unsigned int *order,
|
||||
unsigned int count,
|
||||
struct rnd_state *state);
|
||||
u32 drm_prandom_u32_max_state(u32 ep_ro,
|
||||
u32 gpu_prandom_u32_max_state(u32 ep_ro,
|
||||
struct rnd_state *state);
|
||||
|
||||
#endif /* !__DRM_RANDOM_H__ */
|
||||
#endif /* !__GPU_RANDOM_H__ */
|
||||
|
||||
@@ -37,6 +37,7 @@ source "drivers/char/agp/Kconfig"
|
||||
|
||||
source "drivers/gpu/vga/Kconfig"
|
||||
|
||||
source "drivers/gpu/Kconfig"
|
||||
source "drivers/gpu/host1x/Kconfig"
|
||||
source "drivers/gpu/ipu-v3/Kconfig"
|
||||
source "drivers/gpu/nova-core/Kconfig"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __DRM_BUDDY_H__
|
||||
#define __DRM_BUDDY_H__
|
||||
|
||||
#include <linux/gpu_buddy.h>
|
||||
|
||||
struct drm_printer;
|
||||
|
||||
/* DRM-specific GPU Buddy Allocator print helpers */
|
||||
void drm_buddy_print(struct gpu_buddy *mm, struct drm_printer *p);
|
||||
void drm_buddy_block_print(struct gpu_buddy *mm,
|
||||
struct gpu_buddy_block *block,
|
||||
struct drm_printer *p);
|
||||
#endif
|
||||
+63
-57
@@ -3,8 +3,8 @@
|
||||
* Copyright © 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __DRM_BUDDY_H__
|
||||
#define __DRM_BUDDY_H__
|
||||
#ifndef __GPU_BUDDY_H__
|
||||
#define __GPU_BUDDY_H__
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/list.h>
|
||||
@@ -12,38 +12,45 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/rbtree.h>
|
||||
|
||||
struct drm_printer;
|
||||
#define GPU_BUDDY_RANGE_ALLOCATION BIT(0)
|
||||
#define GPU_BUDDY_TOPDOWN_ALLOCATION BIT(1)
|
||||
#define GPU_BUDDY_CONTIGUOUS_ALLOCATION BIT(2)
|
||||
#define GPU_BUDDY_CLEAR_ALLOCATION BIT(3)
|
||||
#define GPU_BUDDY_CLEARED BIT(4)
|
||||
#define GPU_BUDDY_TRIM_DISABLE BIT(5)
|
||||
|
||||
#define DRM_BUDDY_RANGE_ALLOCATION BIT(0)
|
||||
#define DRM_BUDDY_TOPDOWN_ALLOCATION BIT(1)
|
||||
#define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2)
|
||||
#define DRM_BUDDY_CLEAR_ALLOCATION BIT(3)
|
||||
#define DRM_BUDDY_CLEARED BIT(4)
|
||||
#define DRM_BUDDY_TRIM_DISABLE BIT(5)
|
||||
enum gpu_buddy_free_tree {
|
||||
GPU_BUDDY_CLEAR_TREE = 0,
|
||||
GPU_BUDDY_DIRTY_TREE,
|
||||
GPU_BUDDY_MAX_FREE_TREES,
|
||||
};
|
||||
|
||||
struct drm_buddy_block {
|
||||
#define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
|
||||
#define DRM_BUDDY_HEADER_STATE GENMASK_ULL(11, 10)
|
||||
#define DRM_BUDDY_ALLOCATED (1 << 10)
|
||||
#define DRM_BUDDY_FREE (2 << 10)
|
||||
#define DRM_BUDDY_SPLIT (3 << 10)
|
||||
#define DRM_BUDDY_HEADER_CLEAR GENMASK_ULL(9, 9)
|
||||
#define for_each_free_tree(tree) \
|
||||
for ((tree) = 0; (tree) < GPU_BUDDY_MAX_FREE_TREES; (tree)++)
|
||||
|
||||
struct gpu_buddy_block {
|
||||
#define GPU_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
|
||||
#define GPU_BUDDY_HEADER_STATE GENMASK_ULL(11, 10)
|
||||
#define GPU_BUDDY_ALLOCATED (1 << 10)
|
||||
#define GPU_BUDDY_FREE (2 << 10)
|
||||
#define GPU_BUDDY_SPLIT (3 << 10)
|
||||
#define GPU_BUDDY_HEADER_CLEAR GENMASK_ULL(9, 9)
|
||||
/* Free to be used, if needed in the future */
|
||||
#define DRM_BUDDY_HEADER_UNUSED GENMASK_ULL(8, 6)
|
||||
#define DRM_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0)
|
||||
#define GPU_BUDDY_HEADER_UNUSED GENMASK_ULL(8, 6)
|
||||
#define GPU_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0)
|
||||
u64 header;
|
||||
|
||||
struct drm_buddy_block *left;
|
||||
struct drm_buddy_block *right;
|
||||
struct drm_buddy_block *parent;
|
||||
struct gpu_buddy_block *left;
|
||||
struct gpu_buddy_block *right;
|
||||
struct gpu_buddy_block *parent;
|
||||
|
||||
void *private; /* owned by creator */
|
||||
|
||||
/*
|
||||
* While the block is allocated by the user through drm_buddy_alloc*,
|
||||
* While the block is allocated by the user through gpu_buddy_alloc*,
|
||||
* the user has ownership of the link, for example to maintain within
|
||||
* a list, if so desired. As soon as the block is freed with
|
||||
* drm_buddy_free* ownership is given back to the mm.
|
||||
* gpu_buddy_free* ownership is given back to the mm.
|
||||
*/
|
||||
union {
|
||||
struct rb_node rb;
|
||||
@@ -54,15 +61,15 @@ struct drm_buddy_block {
|
||||
};
|
||||
|
||||
/* Order-zero must be at least SZ_4K */
|
||||
#define DRM_BUDDY_MAX_ORDER (63 - 12)
|
||||
#define GPU_BUDDY_MAX_ORDER (63 - 12)
|
||||
|
||||
/*
|
||||
* Binary Buddy System.
|
||||
*
|
||||
* Locking should be handled by the user, a simple mutex around
|
||||
* drm_buddy_alloc* and drm_buddy_free* should suffice.
|
||||
* gpu_buddy_alloc* and gpu_buddy_free* should suffice.
|
||||
*/
|
||||
struct drm_buddy {
|
||||
struct gpu_buddy {
|
||||
/* Maintain a free list for each order. */
|
||||
struct rb_root **free_trees;
|
||||
|
||||
@@ -73,7 +80,7 @@ struct drm_buddy {
|
||||
* block. Nodes are either allocated or free, in which case they will
|
||||
* also exist on the respective free list.
|
||||
*/
|
||||
struct drm_buddy_block **roots;
|
||||
struct gpu_buddy_block **roots;
|
||||
|
||||
/*
|
||||
* Anything from here is public, and remains static for the lifetime of
|
||||
@@ -90,82 +97,81 @@ struct drm_buddy {
|
||||
};
|
||||
|
||||
static inline u64
|
||||
drm_buddy_block_offset(const struct drm_buddy_block *block)
|
||||
gpu_buddy_block_offset(const struct gpu_buddy_block *block)
|
||||
{
|
||||
return block->header & DRM_BUDDY_HEADER_OFFSET;
|
||||
return block->header & GPU_BUDDY_HEADER_OFFSET;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
drm_buddy_block_order(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_order(struct gpu_buddy_block *block)
|
||||
{
|
||||
return block->header & DRM_BUDDY_HEADER_ORDER;
|
||||
return block->header & GPU_BUDDY_HEADER_ORDER;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
drm_buddy_block_state(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_state(struct gpu_buddy_block *block)
|
||||
{
|
||||
return block->header & DRM_BUDDY_HEADER_STATE;
|
||||
return block->header & GPU_BUDDY_HEADER_STATE;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
drm_buddy_block_is_allocated(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_is_allocated(struct gpu_buddy_block *block)
|
||||
{
|
||||
return drm_buddy_block_state(block) == DRM_BUDDY_ALLOCATED;
|
||||
return gpu_buddy_block_state(block) == GPU_BUDDY_ALLOCATED;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
drm_buddy_block_is_clear(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_is_clear(struct gpu_buddy_block *block)
|
||||
{
|
||||
return block->header & DRM_BUDDY_HEADER_CLEAR;
|
||||
return block->header & GPU_BUDDY_HEADER_CLEAR;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
drm_buddy_block_is_free(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_is_free(struct gpu_buddy_block *block)
|
||||
{
|
||||
return drm_buddy_block_state(block) == DRM_BUDDY_FREE;
|
||||
return gpu_buddy_block_state(block) == GPU_BUDDY_FREE;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
drm_buddy_block_is_split(struct drm_buddy_block *block)
|
||||
gpu_buddy_block_is_split(struct gpu_buddy_block *block)
|
||||
{
|
||||
return drm_buddy_block_state(block) == DRM_BUDDY_SPLIT;
|
||||
return gpu_buddy_block_state(block) == GPU_BUDDY_SPLIT;
|
||||
}
|
||||
|
||||
static inline u64
|
||||
drm_buddy_block_size(struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block)
|
||||
gpu_buddy_block_size(struct gpu_buddy *mm,
|
||||
struct gpu_buddy_block *block)
|
||||
{
|
||||
return mm->chunk_size << drm_buddy_block_order(block);
|
||||
return mm->chunk_size << gpu_buddy_block_order(block);
|
||||
}
|
||||
|
||||
int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size);
|
||||
int gpu_buddy_init(struct gpu_buddy *mm, u64 size, u64 chunk_size);
|
||||
|
||||
void drm_buddy_fini(struct drm_buddy *mm);
|
||||
void gpu_buddy_fini(struct gpu_buddy *mm);
|
||||
|
||||
struct drm_buddy_block *
|
||||
drm_get_buddy(struct drm_buddy_block *block);
|
||||
struct gpu_buddy_block *
|
||||
gpu_get_buddy(struct gpu_buddy_block *block);
|
||||
|
||||
int drm_buddy_alloc_blocks(struct drm_buddy *mm,
|
||||
int gpu_buddy_alloc_blocks(struct gpu_buddy *mm,
|
||||
u64 start, u64 end, u64 size,
|
||||
u64 min_page_size,
|
||||
struct list_head *blocks,
|
||||
unsigned long flags);
|
||||
|
||||
int drm_buddy_block_trim(struct drm_buddy *mm,
|
||||
int gpu_buddy_block_trim(struct gpu_buddy *mm,
|
||||
u64 *start,
|
||||
u64 new_size,
|
||||
struct list_head *blocks);
|
||||
|
||||
void drm_buddy_reset_clear(struct drm_buddy *mm, bool is_clear);
|
||||
void gpu_buddy_reset_clear(struct gpu_buddy *mm, bool is_clear);
|
||||
|
||||
void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
|
||||
void gpu_buddy_free_block(struct gpu_buddy *mm, struct gpu_buddy_block *block);
|
||||
|
||||
void drm_buddy_free_list(struct drm_buddy *mm,
|
||||
void gpu_buddy_free_list(struct gpu_buddy *mm,
|
||||
struct list_head *objects,
|
||||
unsigned int flags);
|
||||
|
||||
void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p);
|
||||
void drm_buddy_block_print(struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block,
|
||||
struct drm_printer *p);
|
||||
void gpu_buddy_print(struct gpu_buddy *mm);
|
||||
void gpu_buddy_block_print(struct gpu_buddy *mm,
|
||||
struct gpu_buddy_block *block);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user