brintos

brintos / linux-shallow public Read only

0
0
Text · 11.1 KiB · 8ade533 Raw
438 lines · c
1// SPDX-License-Identifier: GPL-2.0 AND MIT2/*3 * Copyright © 2023 Intel Corporation4 */5#include <linux/mm.h>6 7#include <drm/ttm/ttm_tt.h>8#include <drm/ttm/ttm_pool.h>9 10#include "ttm_kunit_helpers.h"11 12struct ttm_pool_test_case {13	const char *description;14	unsigned int order;15	bool use_dma_alloc;16};17 18struct ttm_pool_test_priv {19	struct ttm_test_devices *devs;20 21	/* Used to create mock ttm_tts */22	struct ttm_buffer_object *mock_bo;23};24 25static struct ttm_operation_ctx simple_ctx = {26	.interruptible = true,27	.no_wait_gpu = false,28};29 30static int ttm_pool_test_init(struct kunit *test)31{32	struct ttm_pool_test_priv *priv;33 34	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);35	KUNIT_ASSERT_NOT_NULL(test, priv);36 37	priv->devs = ttm_test_devices_basic(test);38	test->priv = priv;39 40	return 0;41}42 43static void ttm_pool_test_fini(struct kunit *test)44{45	struct ttm_pool_test_priv *priv = test->priv;46 47	ttm_test_devices_put(test, priv->devs);48}49 50static struct ttm_tt *ttm_tt_kunit_init(struct kunit *test,51					u32 page_flags,52					enum ttm_caching caching,53					size_t size)54{55	struct ttm_pool_test_priv *priv = test->priv;56	struct ttm_buffer_object *bo;57	struct ttm_tt *tt;58	int err;59 60	bo = ttm_bo_kunit_init(test, priv->devs, size, NULL);61	KUNIT_ASSERT_NOT_NULL(test, bo);62	priv->mock_bo = bo;63 64	tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);65	KUNIT_ASSERT_NOT_NULL(test, tt);66 67	err = ttm_tt_init(tt, priv->mock_bo, page_flags, caching, 0);68	KUNIT_ASSERT_EQ(test, err, 0);69 70	return tt;71}72 73static struct ttm_pool *ttm_pool_pre_populated(struct kunit *test,74					       size_t size,75					       enum ttm_caching caching)76{77	struct ttm_pool_test_priv *priv = test->priv;78	struct ttm_test_devices *devs = priv->devs;79	struct ttm_pool *pool;80	struct ttm_tt *tt;81	int err;82 83	tt = ttm_tt_kunit_init(test, 0, caching, size);84	KUNIT_ASSERT_NOT_NULL(test, tt);85 86	pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);87	KUNIT_ASSERT_NOT_NULL(test, pool);88 89	ttm_pool_init(pool, devs->dev, NUMA_NO_NODE, true, false);90 91	err = ttm_pool_alloc(pool, tt, &simple_ctx);92	KUNIT_ASSERT_EQ(test, err, 0);93 94	ttm_pool_free(pool, tt);95	ttm_tt_fini(tt);96 97	return pool;98}99 100static const struct ttm_pool_test_case ttm_pool_basic_cases[] = {101	{102		.description = "One page",103		.order = 0,104	},105	{106		.description = "More than one page",107		.order = 2,108	},109	{110		.description = "Above the allocation limit",111		.order = MAX_PAGE_ORDER + 1,112	},113	{114		.description = "One page, with coherent DMA mappings enabled",115		.order = 0,116		.use_dma_alloc = true,117	},118	{119		.description = "Above the allocation limit, with coherent DMA mappings enabled",120		.order = MAX_PAGE_ORDER + 1,121		.use_dma_alloc = true,122	},123};124 125static void ttm_pool_alloc_case_desc(const struct ttm_pool_test_case *t,126				     char *desc)127{128	strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);129}130 131KUNIT_ARRAY_PARAM(ttm_pool_alloc_basic, ttm_pool_basic_cases,132		  ttm_pool_alloc_case_desc);133 134static void ttm_pool_alloc_basic(struct kunit *test)135{136	struct ttm_pool_test_priv *priv = test->priv;137	struct ttm_test_devices *devs = priv->devs;138	const struct ttm_pool_test_case *params = test->param_value;139	struct ttm_tt *tt;140	struct ttm_pool *pool;141	struct page *fst_page, *last_page;142	enum ttm_caching caching = ttm_uncached;143	unsigned int expected_num_pages = 1 << params->order;144	size_t size = expected_num_pages * PAGE_SIZE;145	int err;146 147	tt = ttm_tt_kunit_init(test, 0, caching, size);148	KUNIT_ASSERT_NOT_NULL(test, tt);149 150	pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);151	KUNIT_ASSERT_NOT_NULL(test, pool);152 153	ttm_pool_init(pool, devs->dev, NUMA_NO_NODE, params->use_dma_alloc,154		      false);155 156	KUNIT_ASSERT_PTR_EQ(test, pool->dev, devs->dev);157	KUNIT_ASSERT_EQ(test, pool->nid, NUMA_NO_NODE);158	KUNIT_ASSERT_EQ(test, pool->use_dma_alloc, params->use_dma_alloc);159 160	err = ttm_pool_alloc(pool, tt, &simple_ctx);161	KUNIT_ASSERT_EQ(test, err, 0);162	KUNIT_ASSERT_EQ(test, tt->num_pages, expected_num_pages);163 164	fst_page = tt->pages[0];165	last_page = tt->pages[tt->num_pages - 1];166 167	if (params->order <= MAX_PAGE_ORDER) {168		if (params->use_dma_alloc) {169			KUNIT_ASSERT_NOT_NULL(test, (void *)fst_page->private);170			KUNIT_ASSERT_NOT_NULL(test, (void *)last_page->private);171		} else {172			KUNIT_ASSERT_EQ(test, fst_page->private, params->order);173		}174	} else {175		if (params->use_dma_alloc) {176			KUNIT_ASSERT_NOT_NULL(test, (void *)fst_page->private);177			KUNIT_ASSERT_NULL(test, (void *)last_page->private);178		} else {179			/*180			 * We expect to alloc one big block, followed by181			 * order 0 blocks182			 */183			KUNIT_ASSERT_EQ(test, fst_page->private,184					min_t(unsigned int, MAX_PAGE_ORDER,185					      params->order));186			KUNIT_ASSERT_EQ(test, last_page->private, 0);187		}188	}189 190	ttm_pool_free(pool, tt);191	ttm_tt_fini(tt);192	ttm_pool_fini(pool);193}194 195static void ttm_pool_alloc_basic_dma_addr(struct kunit *test)196{197	struct ttm_pool_test_priv *priv = test->priv;198	struct ttm_test_devices *devs = priv->devs;199	const struct ttm_pool_test_case *params = test->param_value;200	struct ttm_tt *tt;201	struct ttm_pool *pool;202	struct ttm_buffer_object *bo;203	dma_addr_t dma1, dma2;204	enum ttm_caching caching = ttm_uncached;205	unsigned int expected_num_pages = 1 << params->order;206	size_t size = expected_num_pages * PAGE_SIZE;207	int err;208 209	tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);210	KUNIT_ASSERT_NOT_NULL(test, tt);211 212	bo = ttm_bo_kunit_init(test, devs, size, NULL);213	KUNIT_ASSERT_NOT_NULL(test, bo);214 215	err = ttm_sg_tt_init(tt, bo, 0, caching);216	KUNIT_ASSERT_EQ(test, err, 0);217 218	pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);219	KUNIT_ASSERT_NOT_NULL(test, pool);220 221	ttm_pool_init(pool, devs->dev, NUMA_NO_NODE, true, false);222 223	err = ttm_pool_alloc(pool, tt, &simple_ctx);224	KUNIT_ASSERT_EQ(test, err, 0);225	KUNIT_ASSERT_EQ(test, tt->num_pages, expected_num_pages);226 227	dma1 = tt->dma_address[0];228	dma2 = tt->dma_address[tt->num_pages - 1];229 230	KUNIT_ASSERT_NOT_NULL(test, (void *)(uintptr_t)dma1);231	KUNIT_ASSERT_NOT_NULL(test, (void *)(uintptr_t)dma2);232 233	ttm_pool_free(pool, tt);234	ttm_tt_fini(tt);235	ttm_pool_fini(pool);236}237 238static void ttm_pool_alloc_order_caching_match(struct kunit *test)239{240	struct ttm_tt *tt;241	struct ttm_pool *pool;242	struct ttm_pool_type *pt;243	enum ttm_caching caching = ttm_uncached;244	unsigned int order = 0;245	size_t size = PAGE_SIZE;246	int err;247 248	pool = ttm_pool_pre_populated(test, size, caching);249 250	pt = &pool->caching[caching].orders[order];251	KUNIT_ASSERT_FALSE(test, list_empty(&pt->pages));252 253	tt = ttm_tt_kunit_init(test, 0, caching, size);254	KUNIT_ASSERT_NOT_NULL(test, tt);255 256	err = ttm_pool_alloc(pool, tt, &simple_ctx);257	KUNIT_ASSERT_EQ(test, err, 0);258 259	KUNIT_ASSERT_TRUE(test, list_empty(&pt->pages));260 261	ttm_pool_free(pool, tt);262	ttm_tt_fini(tt);263	ttm_pool_fini(pool);264}265 266static void ttm_pool_alloc_caching_mismatch(struct kunit *test)267{268	struct ttm_tt *tt;269	struct ttm_pool *pool;270	struct ttm_pool_type *pt_pool, *pt_tt;271	enum ttm_caching tt_caching = ttm_uncached;272	enum ttm_caching pool_caching = ttm_cached;273	size_t size = PAGE_SIZE;274	unsigned int order = 0;275	int err;276 277	pool = ttm_pool_pre_populated(test, size, pool_caching);278 279	pt_pool = &pool->caching[pool_caching].orders[order];280	pt_tt = &pool->caching[tt_caching].orders[order];281 282	tt = ttm_tt_kunit_init(test, 0, tt_caching, size);283	KUNIT_ASSERT_NOT_NULL(test, tt);284 285	KUNIT_ASSERT_FALSE(test, list_empty(&pt_pool->pages));286	KUNIT_ASSERT_TRUE(test, list_empty(&pt_tt->pages));287 288	err = ttm_pool_alloc(pool, tt, &simple_ctx);289	KUNIT_ASSERT_EQ(test, err, 0);290 291	ttm_pool_free(pool, tt);292	ttm_tt_fini(tt);293 294	KUNIT_ASSERT_FALSE(test, list_empty(&pt_pool->pages));295	KUNIT_ASSERT_FALSE(test, list_empty(&pt_tt->pages));296 297	ttm_pool_fini(pool);298}299 300static void ttm_pool_alloc_order_mismatch(struct kunit *test)301{302	struct ttm_tt *tt;303	struct ttm_pool *pool;304	struct ttm_pool_type *pt_pool, *pt_tt;305	enum ttm_caching caching = ttm_uncached;306	unsigned int order = 2;307	size_t fst_size = (1 << order) * PAGE_SIZE;308	size_t snd_size = PAGE_SIZE;309	int err;310 311	pool = ttm_pool_pre_populated(test, fst_size, caching);312 313	pt_pool = &pool->caching[caching].orders[order];314	pt_tt = &pool->caching[caching].orders[0];315 316	tt = ttm_tt_kunit_init(test, 0, caching, snd_size);317	KUNIT_ASSERT_NOT_NULL(test, tt);318 319	KUNIT_ASSERT_FALSE(test, list_empty(&pt_pool->pages));320	KUNIT_ASSERT_TRUE(test, list_empty(&pt_tt->pages));321 322	err = ttm_pool_alloc(pool, tt, &simple_ctx);323	KUNIT_ASSERT_EQ(test, err, 0);324 325	ttm_pool_free(pool, tt);326	ttm_tt_fini(tt);327 328	KUNIT_ASSERT_FALSE(test, list_empty(&pt_pool->pages));329	KUNIT_ASSERT_FALSE(test, list_empty(&pt_tt->pages));330 331	ttm_pool_fini(pool);332}333 334static void ttm_pool_free_dma_alloc(struct kunit *test)335{336	struct ttm_pool_test_priv *priv = test->priv;337	struct ttm_test_devices *devs = priv->devs;338	struct ttm_tt *tt;339	struct ttm_pool *pool;340	struct ttm_pool_type *pt;341	enum ttm_caching caching = ttm_uncached;342	unsigned int order = 2;343	size_t size = (1 << order) * PAGE_SIZE;344 345	tt = ttm_tt_kunit_init(test, 0, caching, size);346	KUNIT_ASSERT_NOT_NULL(test, tt);347 348	pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);349	KUNIT_ASSERT_NOT_NULL(test, pool);350 351	ttm_pool_init(pool, devs->dev, NUMA_NO_NODE, true, false);352	ttm_pool_alloc(pool, tt, &simple_ctx);353 354	pt = &pool->caching[caching].orders[order];355	KUNIT_ASSERT_TRUE(test, list_empty(&pt->pages));356 357	ttm_pool_free(pool, tt);358	ttm_tt_fini(tt);359 360	KUNIT_ASSERT_FALSE(test, list_empty(&pt->pages));361 362	ttm_pool_fini(pool);363}364 365static void ttm_pool_free_no_dma_alloc(struct kunit *test)366{367	struct ttm_pool_test_priv *priv = test->priv;368	struct ttm_test_devices *devs = priv->devs;369	struct ttm_tt *tt;370	struct ttm_pool *pool;371	struct ttm_pool_type *pt;372	enum ttm_caching caching = ttm_uncached;373	unsigned int order = 2;374	size_t size = (1 << order) * PAGE_SIZE;375 376	tt = ttm_tt_kunit_init(test, 0, caching, size);377	KUNIT_ASSERT_NOT_NULL(test, tt);378 379	pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);380	KUNIT_ASSERT_NOT_NULL(test, pool);381 382	ttm_pool_init(pool, devs->dev, NUMA_NO_NODE, false, false);383	ttm_pool_alloc(pool, tt, &simple_ctx);384 385	pt = &pool->caching[caching].orders[order];386	KUNIT_ASSERT_TRUE(test, list_is_singular(&pt->pages));387 388	ttm_pool_free(pool, tt);389	ttm_tt_fini(tt);390 391	KUNIT_ASSERT_TRUE(test, list_is_singular(&pt->pages));392 393	ttm_pool_fini(pool);394}395 396static void ttm_pool_fini_basic(struct kunit *test)397{398	struct ttm_pool *pool;399	struct ttm_pool_type *pt;400	enum ttm_caching caching = ttm_uncached;401	unsigned int order = 0;402	size_t size = PAGE_SIZE;403 404	pool = ttm_pool_pre_populated(test, size, caching);405	pt = &pool->caching[caching].orders[order];406 407	KUNIT_ASSERT_FALSE(test, list_empty(&pt->pages));408 409	ttm_pool_fini(pool);410 411	KUNIT_ASSERT_TRUE(test, list_empty(&pt->pages));412}413 414static struct kunit_case ttm_pool_test_cases[] = {415	KUNIT_CASE_PARAM(ttm_pool_alloc_basic, ttm_pool_alloc_basic_gen_params),416	KUNIT_CASE_PARAM(ttm_pool_alloc_basic_dma_addr,417			 ttm_pool_alloc_basic_gen_params),418	KUNIT_CASE(ttm_pool_alloc_order_caching_match),419	KUNIT_CASE(ttm_pool_alloc_caching_mismatch),420	KUNIT_CASE(ttm_pool_alloc_order_mismatch),421	KUNIT_CASE(ttm_pool_free_dma_alloc),422	KUNIT_CASE(ttm_pool_free_no_dma_alloc),423	KUNIT_CASE(ttm_pool_fini_basic),424	{}425};426 427static struct kunit_suite ttm_pool_test_suite = {428	.name = "ttm_pool",429	.init = ttm_pool_test_init,430	.exit = ttm_pool_test_fini,431	.test_cases = ttm_pool_test_cases,432};433 434kunit_test_suites(&ttm_pool_test_suite);435 436MODULE_DESCRIPTION("KUnit tests for ttm_pool APIs");437MODULE_LICENSE("GPL and additional rights");438