]> Git Repo - linux.git/blob - drivers/gpu/drm/ttm/tests/ttm_resource_test.c
Merge patch series "riscv: Extension parsing fixes"
[linux.git] / drivers / gpu / drm / ttm / tests / ttm_resource_test.c
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
12 struct ttm_resource_test_case {
13         const char *description;
14         uint32_t mem_type;
15         uint32_t flags;
16 };
17
18 struct ttm_resource_test_priv {
19         struct ttm_test_devices *devs;
20         struct ttm_buffer_object *bo;
21         struct ttm_place *place;
22 };
23
24 static const struct ttm_resource_manager_func ttm_resource_manager_mock_funcs = { };
25
26 static 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
41 static 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
48 static 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
61 static 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
80 static 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
100 static 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
105 KUNIT_ARRAY_PARAM(ttm_resource, ttm_resource_cases, ttm_resource_case_desc);
106
107 static 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
151 static 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
181 static 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
205 static 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
226 static 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
252 static 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
264 static 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
289 static 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
314 static 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
326 static 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
333 kunit_test_suites(&ttm_resource_test_suite);
334
335 MODULE_LICENSE("GPL");
This page took 0.053506 seconds and 4 git commands to generate.