Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0 AND MIT
  2/*
  3 * Copyright © 2023 Intel Corporation
  4 */
  5#include <drm/ttm/ttm_resource.h>
  6
  7#include "ttm_kunit_helpers.h"
  8
  9#define RES_SIZE		SZ_4K
 10#define TTM_PRIV_DUMMY_REG	(TTM_NUM_MEM_TYPES - 1)
 11
 12struct ttm_resource_test_case {
 13	const char *description;
 14	uint32_t mem_type;
 15	uint32_t 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				uint32_t mem_type, uint32_t 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);
 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				  uint32_t 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	uint64_t 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));
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	uint64_t 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	uint32_t 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	uint32_t 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_LICENSE("GPL");