]> Git Repo - J-linux.git/blob - drivers/gpu/drm/ttm/tests/ttm_tt_test.c
Merge tag 'sound-6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[J-linux.git] / drivers / gpu / drm / ttm / tests / ttm_tt_test.c
1 // SPDX-License-Identifier: GPL-2.0 AND MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 #include <linux/shmem_fs.h>
6 #include <drm/ttm/ttm_tt.h>
7
8 #include "ttm_kunit_helpers.h"
9
10 #define BO_SIZE         SZ_4K
11
12 struct ttm_tt_test_case {
13         const char *description;
14         uint32_t size;
15         uint32_t extra_pages_num;
16 };
17
18 static int ttm_tt_test_init(struct kunit *test)
19 {
20         struct ttm_test_devices *priv;
21
22         priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
23         KUNIT_ASSERT_NOT_NULL(test, priv);
24
25         priv = ttm_test_devices_all(test);
26         test->priv = priv;
27
28         return 0;
29 }
30
31 static const struct ttm_tt_test_case ttm_tt_init_basic_cases[] = {
32         {
33                 .description = "Page-aligned size",
34                 .size = SZ_4K,
35         },
36         {
37                 .description = "Extra pages requested",
38                 .size = SZ_4K,
39                 .extra_pages_num = 1,
40         },
41 };
42
43 static void ttm_tt_init_case_desc(const struct ttm_tt_test_case *t,
44                                   char *desc)
45 {
46         strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
47 }
48
49 KUNIT_ARRAY_PARAM(ttm_tt_init_basic, ttm_tt_init_basic_cases,
50                   ttm_tt_init_case_desc);
51
52 static void ttm_tt_init_basic(struct kunit *test)
53 {
54         const struct ttm_tt_test_case *params = test->param_value;
55         struct ttm_buffer_object *bo;
56         struct ttm_tt *tt;
57         uint32_t page_flags = TTM_TT_FLAG_ZERO_ALLOC;
58         enum ttm_caching caching = ttm_cached;
59         uint32_t extra_pages = params->extra_pages_num;
60         int num_pages = params->size >> PAGE_SHIFT;
61         int err;
62
63         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
64         KUNIT_ASSERT_NOT_NULL(test, tt);
65
66         bo = ttm_bo_kunit_init(test, test->priv, params->size);
67
68         err = ttm_tt_init(tt, bo, page_flags, caching, extra_pages);
69         KUNIT_ASSERT_EQ(test, err, 0);
70
71         KUNIT_ASSERT_EQ(test, tt->num_pages, num_pages + extra_pages);
72
73         KUNIT_ASSERT_EQ(test, tt->page_flags, page_flags);
74         KUNIT_ASSERT_EQ(test, tt->caching, caching);
75
76         KUNIT_ASSERT_NULL(test, tt->dma_address);
77         KUNIT_ASSERT_NULL(test, tt->swap_storage);
78 }
79
80 static void ttm_tt_init_misaligned(struct kunit *test)
81 {
82         struct ttm_buffer_object *bo;
83         struct ttm_tt *tt;
84         enum ttm_caching caching = ttm_cached;
85         uint32_t size = SZ_8K;
86         int num_pages = (size + SZ_4K) >> PAGE_SHIFT;
87         int err;
88
89         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
90         KUNIT_ASSERT_NOT_NULL(test, tt);
91
92         bo = ttm_bo_kunit_init(test, test->priv, size);
93
94         /* Make the object size misaligned */
95         bo->base.size += 1;
96
97         err = ttm_tt_init(tt, bo, 0, caching, 0);
98         KUNIT_ASSERT_EQ(test, err, 0);
99
100         KUNIT_ASSERT_EQ(test, tt->num_pages, num_pages);
101 }
102
103 static void ttm_tt_fini_basic(struct kunit *test)
104 {
105         struct ttm_buffer_object *bo;
106         struct ttm_tt *tt;
107         enum ttm_caching caching = ttm_cached;
108         int err;
109
110         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
111         KUNIT_ASSERT_NOT_NULL(test, tt);
112
113         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
114
115         err = ttm_tt_init(tt, bo, 0, caching, 0);
116         KUNIT_ASSERT_EQ(test, err, 0);
117         KUNIT_ASSERT_NOT_NULL(test, tt->pages);
118
119         ttm_tt_fini(tt);
120         KUNIT_ASSERT_NULL(test, tt->pages);
121 }
122
123 static void ttm_tt_fini_sg(struct kunit *test)
124 {
125         struct ttm_buffer_object *bo;
126         struct ttm_tt *tt;
127         enum ttm_caching caching = ttm_cached;
128         int err;
129
130         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
131         KUNIT_ASSERT_NOT_NULL(test, tt);
132
133         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
134
135         err = ttm_sg_tt_init(tt, bo, 0, caching);
136         KUNIT_ASSERT_EQ(test, err, 0);
137         KUNIT_ASSERT_NOT_NULL(test, tt->dma_address);
138
139         ttm_tt_fini(tt);
140         KUNIT_ASSERT_NULL(test, tt->dma_address);
141 }
142
143 static void ttm_tt_fini_shmem(struct kunit *test)
144 {
145         struct ttm_buffer_object *bo;
146         struct ttm_tt *tt;
147         struct file *shmem;
148         enum ttm_caching caching = ttm_cached;
149         int err;
150
151         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
152         KUNIT_ASSERT_NOT_NULL(test, tt);
153
154         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
155
156         err = ttm_tt_init(tt, bo, 0, caching, 0);
157         KUNIT_ASSERT_EQ(test, err, 0);
158
159         shmem = shmem_file_setup("ttm swap", BO_SIZE, 0);
160         tt->swap_storage = shmem;
161
162         ttm_tt_fini(tt);
163         KUNIT_ASSERT_NULL(test, tt->swap_storage);
164 }
165
166 static void ttm_tt_create_basic(struct kunit *test)
167 {
168         struct ttm_buffer_object *bo;
169         int err;
170
171         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
172         bo->type = ttm_bo_type_device;
173
174         dma_resv_lock(bo->base.resv, NULL);
175         err = ttm_tt_create(bo, false);
176         dma_resv_unlock(bo->base.resv);
177
178         KUNIT_EXPECT_EQ(test, err, 0);
179         KUNIT_EXPECT_NOT_NULL(test, bo->ttm);
180
181         /* Free manually, as it was allocated outside of KUnit */
182         kfree(bo->ttm);
183 }
184
185 static void ttm_tt_create_invalid_bo_type(struct kunit *test)
186 {
187         struct ttm_buffer_object *bo;
188         int err;
189
190         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
191         bo->type = ttm_bo_type_sg + 1;
192
193         dma_resv_lock(bo->base.resv, NULL);
194         err = ttm_tt_create(bo, false);
195         dma_resv_unlock(bo->base.resv);
196
197         KUNIT_EXPECT_EQ(test, err, -EINVAL);
198         KUNIT_EXPECT_NULL(test, bo->ttm);
199 }
200
201 static void ttm_tt_create_ttm_exists(struct kunit *test)
202 {
203         struct ttm_buffer_object *bo;
204         struct ttm_tt *tt;
205         enum ttm_caching caching = ttm_cached;
206         int err;
207
208         tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
209         KUNIT_ASSERT_NOT_NULL(test, tt);
210
211         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
212
213         err = ttm_tt_init(tt, bo, 0, caching, 0);
214         KUNIT_ASSERT_EQ(test, err, 0);
215         bo->ttm = tt;
216
217         dma_resv_lock(bo->base.resv, NULL);
218         err = ttm_tt_create(bo, false);
219         dma_resv_unlock(bo->base.resv);
220
221         /* Expect to keep the previous TTM */
222         KUNIT_ASSERT_EQ(test, err, 0);
223         KUNIT_ASSERT_PTR_EQ(test, tt, bo->ttm);
224 }
225
226 static struct ttm_tt *ttm_tt_null_create(struct ttm_buffer_object *bo,
227                                          uint32_t page_flags)
228 {
229         return NULL;
230 }
231
232 static struct ttm_device_funcs ttm_dev_empty_funcs = {
233         .ttm_tt_create = ttm_tt_null_create,
234 };
235
236 static void ttm_tt_create_failed(struct kunit *test)
237 {
238         const struct ttm_test_devices *devs = test->priv;
239         struct ttm_buffer_object *bo;
240         int err;
241
242         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
243
244         /* Update ttm_device_funcs so we don't alloc ttm_tt */
245         devs->ttm_dev->funcs = &ttm_dev_empty_funcs;
246
247         dma_resv_lock(bo->base.resv, NULL);
248         err = ttm_tt_create(bo, false);
249         dma_resv_unlock(bo->base.resv);
250
251         KUNIT_ASSERT_EQ(test, err, -ENOMEM);
252 }
253
254 static void ttm_tt_destroy_basic(struct kunit *test)
255 {
256         const struct ttm_test_devices *devs = test->priv;
257         struct ttm_buffer_object *bo;
258         int err;
259
260         bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
261
262         dma_resv_lock(bo->base.resv, NULL);
263         err = ttm_tt_create(bo, false);
264         dma_resv_unlock(bo->base.resv);
265
266         KUNIT_ASSERT_EQ(test, err, 0);
267         KUNIT_ASSERT_NOT_NULL(test, bo->ttm);
268
269         ttm_tt_destroy(devs->ttm_dev, bo->ttm);
270 }
271
272 static struct kunit_case ttm_tt_test_cases[] = {
273         KUNIT_CASE_PARAM(ttm_tt_init_basic, ttm_tt_init_basic_gen_params),
274         KUNIT_CASE(ttm_tt_init_misaligned),
275         KUNIT_CASE(ttm_tt_fini_basic),
276         KUNIT_CASE(ttm_tt_fini_sg),
277         KUNIT_CASE(ttm_tt_fini_shmem),
278         KUNIT_CASE(ttm_tt_create_basic),
279         KUNIT_CASE(ttm_tt_create_invalid_bo_type),
280         KUNIT_CASE(ttm_tt_create_ttm_exists),
281         KUNIT_CASE(ttm_tt_create_failed),
282         KUNIT_CASE(ttm_tt_destroy_basic),
283         {}
284 };
285
286 static struct kunit_suite ttm_tt_test_suite = {
287         .name = "ttm_tt",
288         .init = ttm_tt_test_init,
289         .exit = ttm_test_devices_fini,
290         .test_cases = ttm_tt_test_cases,
291 };
292
293 kunit_test_suites(&ttm_tt_test_suite);
294
295 MODULE_LICENSE("GPL");
This page took 0.045213 seconds and 4 git commands to generate.