| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- // SPDX-License-Identifier: GPL-2.0 AND MIT
- /*
- * Copyright © 2023 Intel Corporation
- */
- #include <drm/ttm/ttm_resource.h>
- #include "ttm_kunit_helpers.h"
- #define RES_SIZE SZ_4K
- #define TTM_PRIV_DUMMY_REG (TTM_NUM_MEM_TYPES - 1)
- struct ttm_resource_test_case {
- const char *description;
- u32 mem_type;
- u32 flags;
- };
- struct ttm_resource_test_priv {
- struct ttm_test_devices *devs;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- };
- static const struct ttm_resource_manager_func ttm_resource_manager_mock_funcs = { };
- static int ttm_resource_test_init(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv;
- priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, priv);
- priv->devs = ttm_test_devices_all(test);
- KUNIT_ASSERT_NOT_NULL(test, priv->devs);
- test->priv = priv;
- return 0;
- }
- static void ttm_resource_test_fini(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- ttm_test_devices_put(test, priv->devs);
- }
- static void ttm_init_test_mocks(struct kunit *test,
- struct ttm_resource_test_priv *priv,
- u32 mem_type, u32 flags)
- {
- size_t size = RES_SIZE;
- /* Make sure we have what we need for a good BO mock */
- KUNIT_ASSERT_NOT_NULL(test, priv->devs->ttm_dev);
- priv->bo = ttm_bo_kunit_init(test, priv->devs, size, NULL);
- priv->place = ttm_place_kunit_init(test, mem_type, flags);
- }
- static void ttm_init_test_manager(struct kunit *test,
- struct ttm_resource_test_priv *priv,
- u32 mem_type)
- {
- struct ttm_device *ttm_dev = priv->devs->ttm_dev;
- struct ttm_resource_manager *man;
- size_t size = SZ_16K;
- man = kunit_kzalloc(test, sizeof(*man), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, man);
- man->use_tt = false;
- man->func = &ttm_resource_manager_mock_funcs;
- ttm_resource_manager_init(man, ttm_dev, size);
- ttm_set_driver_manager(ttm_dev, mem_type, man);
- ttm_resource_manager_set_used(man, true);
- }
- static const struct ttm_resource_test_case ttm_resource_cases[] = {
- {
- .description = "Init resource in TTM_PL_SYSTEM",
- .mem_type = TTM_PL_SYSTEM,
- },
- {
- .description = "Init resource in TTM_PL_VRAM",
- .mem_type = TTM_PL_VRAM,
- },
- {
- .description = "Init resource in a private placement",
- .mem_type = TTM_PRIV_DUMMY_REG,
- },
- {
- .description = "Init resource in TTM_PL_SYSTEM, set placement flags",
- .mem_type = TTM_PL_SYSTEM,
- .flags = TTM_PL_FLAG_TOPDOWN,
- },
- };
- static void ttm_resource_case_desc(const struct ttm_resource_test_case *t, char *desc)
- {
- strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
- }
- KUNIT_ARRAY_PARAM(ttm_resource, ttm_resource_cases, ttm_resource_case_desc);
- static void ttm_resource_init_basic(struct kunit *test)
- {
- const struct ttm_resource_test_case *params = test->param_value;
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource *res;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource_manager *man;
- u64 expected_usage;
- ttm_init_test_mocks(test, priv, params->mem_type, params->flags);
- bo = priv->bo;
- place = priv->place;
- if (params->mem_type > TTM_PL_SYSTEM)
- ttm_init_test_manager(test, priv, params->mem_type);
- res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, res);
- man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);
- expected_usage = man->usage + RES_SIZE;
- KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[bo->priority]));
- ttm_resource_init(bo, place, res);
- KUNIT_ASSERT_EQ(test, res->start, 0);
- KUNIT_ASSERT_EQ(test, res->size, RES_SIZE);
- KUNIT_ASSERT_EQ(test, res->mem_type, place->mem_type);
- KUNIT_ASSERT_EQ(test, res->placement, place->flags);
- KUNIT_ASSERT_PTR_EQ(test, res->bo, bo);
- KUNIT_ASSERT_NULL(test, res->bus.addr);
- KUNIT_ASSERT_EQ(test, res->bus.offset, 0);
- KUNIT_ASSERT_FALSE(test, res->bus.is_iomem);
- KUNIT_ASSERT_EQ(test, res->bus.caching, ttm_cached);
- KUNIT_ASSERT_EQ(test, man->usage, expected_usage);
- KUNIT_ASSERT_TRUE(test, list_is_singular(&man->lru[bo->priority]));
- ttm_resource_fini(man, res);
- }
- static void ttm_resource_init_pinned(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource *res;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource_manager *man;
- ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, 0);
- bo = priv->bo;
- place = priv->place;
- man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);
- res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, res);
- KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable));
- dma_resv_lock(bo->base.resv, NULL);
- ttm_bo_pin(bo);
- ttm_resource_init(bo, place, res);
- KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->unevictable));
- ttm_bo_unpin(bo);
- ttm_resource_fini(man, res);
- dma_resv_unlock(bo->base.resv);
- KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable));
- }
- static void ttm_resource_fini_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource *res;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource_manager *man;
- ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, 0);
- bo = priv->bo;
- place = priv->place;
- man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);
- res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, res);
- ttm_resource_init(bo, place, res);
- ttm_resource_fini(man, res);
- KUNIT_ASSERT_TRUE(test, list_empty(&res->lru.link));
- KUNIT_ASSERT_EQ(test, man->usage, 0);
- }
- static void ttm_resource_manager_init_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource_manager *man;
- size_t size = SZ_16K;
- int i;
- man = kunit_kzalloc(test, sizeof(*man), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, man);
- ttm_resource_manager_init(man, priv->devs->ttm_dev, size);
- KUNIT_ASSERT_PTR_EQ(test, man->bdev, priv->devs->ttm_dev);
- KUNIT_ASSERT_EQ(test, man->size, size);
- KUNIT_ASSERT_EQ(test, man->usage, 0);
- for (i = 0; i < TTM_NUM_MOVE_FENCES; i++)
- KUNIT_ASSERT_NULL(test, man->eviction_fences[i]);
- for (int i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
- KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[i]));
- }
- static void ttm_resource_manager_usage_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource *res;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource_manager *man;
- u64 actual_usage;
- ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, TTM_PL_FLAG_TOPDOWN);
- bo = priv->bo;
- place = priv->place;
- res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, res);
- man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);
- ttm_resource_init(bo, place, res);
- actual_usage = ttm_resource_manager_usage(man);
- KUNIT_ASSERT_EQ(test, actual_usage, RES_SIZE);
- ttm_resource_fini(man, res);
- }
- static void ttm_resource_manager_set_used_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource_manager *man;
- man = ttm_manager_type(priv->devs->ttm_dev, TTM_PL_SYSTEM);
- KUNIT_ASSERT_TRUE(test, man->use_type);
- ttm_resource_manager_set_used(man, false);
- KUNIT_ASSERT_FALSE(test, man->use_type);
- }
- static void ttm_sys_man_alloc_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource_manager *man;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource *res;
- u32 mem_type = TTM_PL_SYSTEM;
- int ret;
- ttm_init_test_mocks(test, priv, mem_type, 0);
- bo = priv->bo;
- place = priv->place;
- man = ttm_manager_type(priv->devs->ttm_dev, mem_type);
- ret = man->func->alloc(man, bo, place, &res);
- KUNIT_ASSERT_EQ(test, ret, 0);
- KUNIT_ASSERT_EQ(test, res->size, RES_SIZE);
- KUNIT_ASSERT_EQ(test, res->mem_type, mem_type);
- KUNIT_ASSERT_PTR_EQ(test, res->bo, bo);
- ttm_resource_fini(man, res);
- }
- static void ttm_sys_man_free_basic(struct kunit *test)
- {
- struct ttm_resource_test_priv *priv = test->priv;
- struct ttm_resource_manager *man;
- struct ttm_buffer_object *bo;
- struct ttm_place *place;
- struct ttm_resource *res;
- u32 mem_type = TTM_PL_SYSTEM;
- ttm_init_test_mocks(test, priv, mem_type, 0);
- bo = priv->bo;
- place = priv->place;
- res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
- KUNIT_ASSERT_NOT_NULL(test, res);
- ttm_resource_alloc(bo, place, &res, NULL);
- man = ttm_manager_type(priv->devs->ttm_dev, mem_type);
- man->func->free(man, res);
- KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[bo->priority]));
- KUNIT_ASSERT_EQ(test, man->usage, 0);
- }
- static struct kunit_case ttm_resource_test_cases[] = {
- KUNIT_CASE_PARAM(ttm_resource_init_basic, ttm_resource_gen_params),
- KUNIT_CASE(ttm_resource_init_pinned),
- KUNIT_CASE(ttm_resource_fini_basic),
- KUNIT_CASE(ttm_resource_manager_init_basic),
- KUNIT_CASE(ttm_resource_manager_usage_basic),
- KUNIT_CASE(ttm_resource_manager_set_used_basic),
- KUNIT_CASE(ttm_sys_man_alloc_basic),
- KUNIT_CASE(ttm_sys_man_free_basic),
- {}
- };
- static struct kunit_suite ttm_resource_test_suite = {
- .name = "ttm_resource",
- .init = ttm_resource_test_init,
- .exit = ttm_resource_test_fini,
- .test_cases = ttm_resource_test_cases,
- };
- kunit_test_suites(&ttm_resource_test_suite);
- MODULE_DESCRIPTION("KUnit tests for ttm_resource and ttm_sys_man APIs");
- MODULE_LICENSE("GPL and additional rights");
|