Commit 32d618e9 authored by Karolina Stolarek's avatar Karolina Stolarek Committed by Arunpravin Paneer Selvam

drm/ttm/tests: Add tests with mock resource managers

Add mock resource manager to test ttm_bo_validate() with non-system
placements. Update KConfig entry to enable DRM Buddy allocator, used
by the mock manager. Update move function to do more than just assign
a resource.
Signed-off-by: default avatarKarolina Stolarek <karolina.stolarek@intel.com>
Tested-by: default avatarSomalapuram, Amaranath <asomalap@amd.com>
Reviewed-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: default avatarArunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/664791dbb7cbada29e705d2fcaf176023f1b8649.1718192625.git.karolina.stolarek@intel.com
parent 8bd1ff5d
......@@ -248,6 +248,7 @@ config DRM_TTM_KUNIT_TEST
default n
depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
select DRM_TTM
select DRM_BUDDY
select DRM_EXPORT_FOR_TESTS if m
select DRM_KUNIT_TEST_HELPERS
default KUNIT_ALL_TESTS
......
......@@ -7,4 +7,5 @@ obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \
ttm_tt_test.o \
ttm_bo_test.o \
ttm_bo_validate_test.o \
ttm_mock_manager.o \
ttm_kunit_helpers.o
......@@ -27,8 +27,31 @@ static int mock_move(struct ttm_buffer_object *bo, bool evict,
struct ttm_resource *new_mem,
struct ttm_place *hop)
{
bo->resource = new_mem;
return 0;
struct ttm_resource *old_mem = bo->resource;
if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm)) {
ttm_bo_move_null(bo, new_mem);
return 0;
}
if (bo->resource->mem_type == TTM_PL_VRAM &&
new_mem->mem_type == TTM_PL_SYSTEM) {
hop->mem_type = TTM_PL_TT;
hop->flags = TTM_PL_FLAG_TEMPORARY;
hop->fpfn = 0;
hop->lpfn = 0;
return -EMULTIHOP;
}
if ((old_mem->mem_type == TTM_PL_SYSTEM &&
new_mem->mem_type == TTM_PL_TT) ||
(old_mem->mem_type == TTM_PL_TT &&
new_mem->mem_type == TTM_PL_SYSTEM)) {
ttm_bo_move_null(bo, new_mem);
return 0;
}
return ttm_bo_move_memcpy(bo, ctx, new_mem);
}
struct ttm_device_funcs ttm_dev_funcs = {
......
// SPDX-License-Identifier: GPL-2.0 AND MIT
/*
* Copyright © 2023 Intel Corporation
*/
#include <drm/ttm/ttm_resource.h>
#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
#include "ttm_mock_manager.h"
static inline struct ttm_mock_manager *
to_mock_mgr(struct ttm_resource_manager *man)
{
return container_of(man, struct ttm_mock_manager, man);
}
static inline struct ttm_mock_resource *
to_mock_mgr_resource(struct ttm_resource *res)
{
return container_of(res, struct ttm_mock_resource, base);
}
static int ttm_mock_manager_alloc(struct ttm_resource_manager *man,
struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res)
{
struct ttm_mock_manager *manager = to_mock_mgr(man);
struct ttm_mock_resource *mock_res;
struct drm_buddy *mm = &manager->mm;
u64 lpfn, fpfn, alloc_size;
int err;
mock_res = kzalloc(sizeof(*mock_res), GFP_KERNEL);
if (!mock_res)
return -ENOMEM;
fpfn = 0;
lpfn = man->size;
ttm_resource_init(bo, place, &mock_res->base);
INIT_LIST_HEAD(&mock_res->blocks);
if (place->flags & TTM_PL_FLAG_TOPDOWN)
mock_res->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
mock_res->flags |= DRM_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,
manager->default_page_size,
&mock_res->blocks,
mock_res->flags);
if (err)
goto error_free_blocks;
mutex_unlock(&manager->lock);
*res = &mock_res->base;
return 0;
error_free_blocks:
drm_buddy_free_list(mm, &mock_res->blocks, 0);
ttm_resource_fini(man, &mock_res->base);
mutex_unlock(&manager->lock);
return err;
}
static void ttm_mock_manager_free(struct ttm_resource_manager *man,
struct ttm_resource *res)
{
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;
mutex_lock(&manager->lock);
drm_buddy_free_list(mm, &mock_res->blocks, 0);
mutex_unlock(&manager->lock);
ttm_resource_fini(man, res);
kfree(mock_res);
}
static const struct ttm_resource_manager_func ttm_mock_manager_funcs = {
.alloc = ttm_mock_manager_alloc,
.free = ttm_mock_manager_free,
};
int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
{
struct ttm_mock_manager *manager;
struct ttm_resource_manager *base;
int err;
manager = kzalloc(sizeof(*manager), GFP_KERNEL);
if (!manager)
return -ENOMEM;
mutex_init(&manager->lock);
err = drm_buddy_init(&manager->mm, size, PAGE_SIZE);
if (err) {
kfree(manager);
return err;
}
manager->default_page_size = PAGE_SIZE;
base = &manager->man;
base->func = &ttm_mock_manager_funcs;
base->use_tt = true;
ttm_resource_manager_init(base, bdev, size);
ttm_set_driver_manager(bdev, mem_type, base);
ttm_resource_manager_set_used(base, true);
return 0;
}
EXPORT_SYMBOL_GPL(ttm_mock_manager_init);
void ttm_mock_manager_fini(struct ttm_device *bdev, u32 mem_type)
{
struct ttm_resource_manager *man;
struct ttm_mock_manager *mock_man;
int err;
man = ttm_manager_type(bdev, mem_type);
mock_man = to_mock_mgr(man);
err = ttm_resource_manager_evict_all(bdev, man);
if (err)
return;
ttm_resource_manager_set_used(man, false);
mutex_lock(&mock_man->lock);
drm_buddy_fini(&mock_man->mm);
mutex_unlock(&mock_man->lock);
ttm_set_driver_manager(bdev, mem_type, NULL);
}
EXPORT_SYMBOL_GPL(ttm_mock_manager_fini);
static int ttm_bad_manager_alloc(struct ttm_resource_manager *man,
struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res)
{
return -ENOSPC;
}
static void ttm_bad_manager_free(struct ttm_resource_manager *man,
struct ttm_resource *res)
{
}
static bool ttm_bad_manager_compatible(struct ttm_resource_manager *man,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size)
{
return true;
}
static const struct ttm_resource_manager_func ttm_bad_manager_funcs = {
.alloc = ttm_bad_manager_alloc,
.free = ttm_bad_manager_free,
.compatible = ttm_bad_manager_compatible
};
int ttm_bad_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
{
struct ttm_resource_manager *man;
man = kzalloc(sizeof(*man), GFP_KERNEL);
if (!man)
return -ENOMEM;
man->func = &ttm_bad_manager_funcs;
ttm_resource_manager_init(man, bdev, size);
ttm_set_driver_manager(bdev, mem_type, man);
ttm_resource_manager_set_used(man, true);
return 0;
}
EXPORT_SYMBOL_GPL(ttm_bad_manager_init);
void ttm_bad_manager_fini(struct ttm_device *bdev, u32 mem_type)
{
struct ttm_resource_manager *man;
man = ttm_manager_type(bdev, mem_type);
ttm_resource_manager_set_used(man, false);
ttm_set_driver_manager(bdev, mem_type, NULL);
kfree(man);
}
EXPORT_SYMBOL_GPL(ttm_bad_manager_fini);
MODULE_LICENSE("GPL and additional rights");
/* SPDX-License-Identifier: GPL-2.0 AND MIT */
/*
* Copyright © 2023 Intel Corporation
*/
#ifndef TTM_MOCK_MANAGER_H
#define TTM_MOCK_MANAGER_H
#include <drm/drm_buddy.h>
struct ttm_mock_manager {
struct ttm_resource_manager man;
struct drm_buddy mm;
u64 default_page_size;
/* protects allocations of mock buffer objects */
struct mutex lock;
};
struct ttm_mock_resource {
struct ttm_resource base;
struct list_head blocks;
unsigned long flags;
};
int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size);
int ttm_bad_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size);
void ttm_mock_manager_fini(struct ttm_device *bdev, u32 mem_type);
void ttm_bad_manager_fini(struct ttm_device *bdev, u32 mem_type);
#endif // TTM_MOCK_MANAGER_H
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment