brintos

brintos / linux-shallow public Read only

0
0
Text · 9.0 KiB · 22260e7 Raw
337 lines · c
1// SPDX-License-Identifier: GPL-2.0 AND MIT2/*3 * Copyright © 2023 Intel Corporation4 */5#include <drm/ttm/ttm_resource.h>6 7#include "ttm_kunit_helpers.h"8 9#define RES_SIZE		SZ_4K10#define TTM_PRIV_DUMMY_REG	(TTM_NUM_MEM_TYPES - 1)11 12struct ttm_resource_test_case {13	const char *description;14	u32 mem_type;15	u32 flags;16};17 18struct ttm_resource_test_priv {19	struct ttm_test_devices *devs;20	struct ttm_buffer_object *bo;21	struct ttm_place *place;22};23 24static const struct ttm_resource_manager_func ttm_resource_manager_mock_funcs = { };25 26static int ttm_resource_test_init(struct kunit *test)27{28	struct ttm_resource_test_priv *priv;29 30	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);31	KUNIT_ASSERT_NOT_NULL(test, priv);32 33	priv->devs = ttm_test_devices_all(test);34	KUNIT_ASSERT_NOT_NULL(test, priv->devs);35 36	test->priv = priv;37 38	return 0;39}40 41static void ttm_resource_test_fini(struct kunit *test)42{43	struct ttm_resource_test_priv *priv = test->priv;44 45	ttm_test_devices_put(test, priv->devs);46}47 48static void ttm_init_test_mocks(struct kunit *test,49				struct ttm_resource_test_priv *priv,50				u32 mem_type, u32 flags)51{52	size_t size = RES_SIZE;53 54	/* Make sure we have what we need for a good BO mock */55	KUNIT_ASSERT_NOT_NULL(test, priv->devs->ttm_dev);56 57	priv->bo = ttm_bo_kunit_init(test, priv->devs, size, NULL);58	priv->place = ttm_place_kunit_init(test, mem_type, flags);59}60 61static void ttm_init_test_manager(struct kunit *test,62				  struct ttm_resource_test_priv *priv,63				  u32 mem_type)64{65	struct ttm_device *ttm_dev = priv->devs->ttm_dev;66	struct ttm_resource_manager *man;67	size_t size = SZ_16K;68 69	man = kunit_kzalloc(test, sizeof(*man), GFP_KERNEL);70	KUNIT_ASSERT_NOT_NULL(test, man);71 72	man->use_tt = false;73	man->func = &ttm_resource_manager_mock_funcs;74 75	ttm_resource_manager_init(man, ttm_dev, size);76	ttm_set_driver_manager(ttm_dev, mem_type, man);77	ttm_resource_manager_set_used(man, true);78}79 80static const struct ttm_resource_test_case ttm_resource_cases[] = {81	{82		.description = "Init resource in TTM_PL_SYSTEM",83		.mem_type = TTM_PL_SYSTEM,84	},85	{86		.description = "Init resource in TTM_PL_VRAM",87		.mem_type = TTM_PL_VRAM,88	},89	{90		.description = "Init resource in a private placement",91		.mem_type = TTM_PRIV_DUMMY_REG,92	},93	{94		.description = "Init resource in TTM_PL_SYSTEM, set placement flags",95		.mem_type = TTM_PL_SYSTEM,96		.flags = TTM_PL_FLAG_TOPDOWN,97	},98};99 100static void ttm_resource_case_desc(const struct ttm_resource_test_case *t, char *desc)101{102	strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);103}104 105KUNIT_ARRAY_PARAM(ttm_resource, ttm_resource_cases, ttm_resource_case_desc);106 107static void ttm_resource_init_basic(struct kunit *test)108{109	const struct ttm_resource_test_case *params = test->param_value;110	struct ttm_resource_test_priv *priv = test->priv;111	struct ttm_resource *res;112	struct ttm_buffer_object *bo;113	struct ttm_place *place;114	struct ttm_resource_manager *man;115	u64 expected_usage;116 117	ttm_init_test_mocks(test, priv, params->mem_type, params->flags);118	bo = priv->bo;119	place = priv->place;120 121	if (params->mem_type > TTM_PL_SYSTEM)122		ttm_init_test_manager(test, priv, params->mem_type);123 124	res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);125	KUNIT_ASSERT_NOT_NULL(test, res);126 127	man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);128	expected_usage = man->usage + RES_SIZE;129 130	KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[bo->priority]));131 132	ttm_resource_init(bo, place, res);133 134	KUNIT_ASSERT_EQ(test, res->start, 0);135	KUNIT_ASSERT_EQ(test, res->size, RES_SIZE);136	KUNIT_ASSERT_EQ(test, res->mem_type, place->mem_type);137	KUNIT_ASSERT_EQ(test, res->placement, place->flags);138	KUNIT_ASSERT_PTR_EQ(test, res->bo, bo);139 140	KUNIT_ASSERT_NULL(test, res->bus.addr);141	KUNIT_ASSERT_EQ(test, res->bus.offset, 0);142	KUNIT_ASSERT_FALSE(test, res->bus.is_iomem);143	KUNIT_ASSERT_EQ(test, res->bus.caching, ttm_cached);144	KUNIT_ASSERT_EQ(test, man->usage, expected_usage);145 146	KUNIT_ASSERT_TRUE(test, list_is_singular(&man->lru[bo->priority]));147 148	ttm_resource_fini(man, res);149}150 151static void ttm_resource_init_pinned(struct kunit *test)152{153	struct ttm_resource_test_priv *priv = test->priv;154	struct ttm_resource *res;155	struct ttm_buffer_object *bo;156	struct ttm_place *place;157	struct ttm_resource_manager *man;158 159	ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, 0);160	bo = priv->bo;161	place = priv->place;162 163	man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);164 165	res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);166	KUNIT_ASSERT_NOT_NULL(test, res);167	KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned));168 169	dma_resv_lock(bo->base.resv, NULL);170	ttm_bo_pin(bo);171	ttm_resource_init(bo, place, res);172	KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->pinned));173 174	ttm_bo_unpin(bo);175	ttm_resource_fini(man, res);176	dma_resv_unlock(bo->base.resv);177 178	KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned));179}180 181static void ttm_resource_fini_basic(struct kunit *test)182{183	struct ttm_resource_test_priv *priv = test->priv;184	struct ttm_resource *res;185	struct ttm_buffer_object *bo;186	struct ttm_place *place;187	struct ttm_resource_manager *man;188 189	ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, 0);190	bo = priv->bo;191	place = priv->place;192 193	man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);194 195	res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);196	KUNIT_ASSERT_NOT_NULL(test, res);197 198	ttm_resource_init(bo, place, res);199	ttm_resource_fini(man, res);200 201	KUNIT_ASSERT_TRUE(test, list_empty(&res->lru.link));202	KUNIT_ASSERT_EQ(test, man->usage, 0);203}204 205static void ttm_resource_manager_init_basic(struct kunit *test)206{207	struct ttm_resource_test_priv *priv = test->priv;208	struct ttm_resource_manager *man;209	size_t size = SZ_16K;210 211	man = kunit_kzalloc(test, sizeof(*man), GFP_KERNEL);212	KUNIT_ASSERT_NOT_NULL(test, man);213 214	ttm_resource_manager_init(man, priv->devs->ttm_dev, size);215 216	KUNIT_ASSERT_PTR_EQ(test, man->bdev, priv->devs->ttm_dev);217	KUNIT_ASSERT_EQ(test, man->size, size);218	KUNIT_ASSERT_EQ(test, man->usage, 0);219	KUNIT_ASSERT_NULL(test, man->move);220	KUNIT_ASSERT_NOT_NULL(test, &man->move_lock);221 222	for (int i = 0; i < TTM_MAX_BO_PRIORITY; ++i)223		KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[i]));224}225 226static void ttm_resource_manager_usage_basic(struct kunit *test)227{228	struct ttm_resource_test_priv *priv = test->priv;229	struct ttm_resource *res;230	struct ttm_buffer_object *bo;231	struct ttm_place *place;232	struct ttm_resource_manager *man;233	u64 actual_usage;234 235	ttm_init_test_mocks(test, priv, TTM_PL_SYSTEM, TTM_PL_FLAG_TOPDOWN);236	bo = priv->bo;237	place = priv->place;238 239	res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);240	KUNIT_ASSERT_NOT_NULL(test, res);241 242	man = ttm_manager_type(priv->devs->ttm_dev, place->mem_type);243 244	ttm_resource_init(bo, place, res);245	actual_usage = ttm_resource_manager_usage(man);246 247	KUNIT_ASSERT_EQ(test, actual_usage, RES_SIZE);248 249	ttm_resource_fini(man, res);250}251 252static void ttm_resource_manager_set_used_basic(struct kunit *test)253{254	struct ttm_resource_test_priv *priv = test->priv;255	struct ttm_resource_manager *man;256 257	man = ttm_manager_type(priv->devs->ttm_dev, TTM_PL_SYSTEM);258	KUNIT_ASSERT_TRUE(test, man->use_type);259 260	ttm_resource_manager_set_used(man, false);261	KUNIT_ASSERT_FALSE(test, man->use_type);262}263 264static void ttm_sys_man_alloc_basic(struct kunit *test)265{266	struct ttm_resource_test_priv *priv = test->priv;267	struct ttm_resource_manager *man;268	struct ttm_buffer_object *bo;269	struct ttm_place *place;270	struct ttm_resource *res;271	u32 mem_type = TTM_PL_SYSTEM;272	int ret;273 274	ttm_init_test_mocks(test, priv, mem_type, 0);275	bo = priv->bo;276	place = priv->place;277 278	man = ttm_manager_type(priv->devs->ttm_dev, mem_type);279	ret = man->func->alloc(man, bo, place, &res);280 281	KUNIT_ASSERT_EQ(test, ret, 0);282	KUNIT_ASSERT_EQ(test, res->size, RES_SIZE);283	KUNIT_ASSERT_EQ(test, res->mem_type, mem_type);284	KUNIT_ASSERT_PTR_EQ(test, res->bo, bo);285 286	ttm_resource_fini(man, res);287}288 289static void ttm_sys_man_free_basic(struct kunit *test)290{291	struct ttm_resource_test_priv *priv = test->priv;292	struct ttm_resource_manager *man;293	struct ttm_buffer_object *bo;294	struct ttm_place *place;295	struct ttm_resource *res;296	u32 mem_type = TTM_PL_SYSTEM;297 298	ttm_init_test_mocks(test, priv, mem_type, 0);299	bo = priv->bo;300	place = priv->place;301 302	res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);303	KUNIT_ASSERT_NOT_NULL(test, res);304 305	ttm_resource_alloc(bo, place, &res);306 307	man = ttm_manager_type(priv->devs->ttm_dev, mem_type);308	man->func->free(man, res);309 310	KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[bo->priority]));311	KUNIT_ASSERT_EQ(test, man->usage, 0);312}313 314static struct kunit_case ttm_resource_test_cases[] = {315	KUNIT_CASE_PARAM(ttm_resource_init_basic, ttm_resource_gen_params),316	KUNIT_CASE(ttm_resource_init_pinned),317	KUNIT_CASE(ttm_resource_fini_basic),318	KUNIT_CASE(ttm_resource_manager_init_basic),319	KUNIT_CASE(ttm_resource_manager_usage_basic),320	KUNIT_CASE(ttm_resource_manager_set_used_basic),321	KUNIT_CASE(ttm_sys_man_alloc_basic),322	KUNIT_CASE(ttm_sys_man_free_basic),323	{}324};325 326static struct kunit_suite ttm_resource_test_suite = {327	.name = "ttm_resource",328	.init = ttm_resource_test_init,329	.exit = ttm_resource_test_fini,330	.test_cases = ttm_resource_test_cases,331};332 333kunit_test_suites(&ttm_resource_test_suite);334 335MODULE_DESCRIPTION("KUnit tests for ttm_resource and ttm_sys_man APIs");336MODULE_LICENSE("GPL and additional rights");337