]> Git Repo - linux.git/blob - drivers/gpu/drm/ttm/tests/ttm_mock_manager.c
Linux 6.14-rc3
[linux.git] / drivers / gpu / drm / ttm / tests / ttm_mock_manager.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 #include <drm/ttm/ttm_device.h>
7 #include <drm/ttm/ttm_placement.h>
8
9 #include "ttm_mock_manager.h"
10
11 static inline struct ttm_mock_manager *
12 to_mock_mgr(struct ttm_resource_manager *man)
13 {
14         return container_of(man, struct ttm_mock_manager, man);
15 }
16
17 static inline struct ttm_mock_resource *
18 to_mock_mgr_resource(struct ttm_resource *res)
19 {
20         return container_of(res, struct ttm_mock_resource, base);
21 }
22
23 static int ttm_mock_manager_alloc(struct ttm_resource_manager *man,
24                                   struct ttm_buffer_object *bo,
25                                   const struct ttm_place *place,
26                                   struct ttm_resource **res)
27 {
28         struct ttm_mock_manager *manager = to_mock_mgr(man);
29         struct ttm_mock_resource *mock_res;
30         struct drm_buddy *mm = &manager->mm;
31         u64 lpfn, fpfn, alloc_size;
32         int err;
33
34         mock_res = kzalloc(sizeof(*mock_res), GFP_KERNEL);
35
36         if (!mock_res)
37                 return -ENOMEM;
38
39         fpfn = 0;
40         lpfn = man->size;
41
42         ttm_resource_init(bo, place, &mock_res->base);
43         INIT_LIST_HEAD(&mock_res->blocks);
44
45         if (place->flags & TTM_PL_FLAG_TOPDOWN)
46                 mock_res->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
47
48         if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
49                 mock_res->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
50
51         alloc_size = (uint64_t)mock_res->base.size;
52         mutex_lock(&manager->lock);
53         err = drm_buddy_alloc_blocks(mm, fpfn, lpfn, alloc_size,
54                                      manager->default_page_size,
55                                      &mock_res->blocks,
56                                      mock_res->flags);
57
58         if (err)
59                 goto error_free_blocks;
60         mutex_unlock(&manager->lock);
61
62         *res = &mock_res->base;
63         return 0;
64
65 error_free_blocks:
66         drm_buddy_free_list(mm, &mock_res->blocks, 0);
67         ttm_resource_fini(man, &mock_res->base);
68         mutex_unlock(&manager->lock);
69
70         return err;
71 }
72
73 static void ttm_mock_manager_free(struct ttm_resource_manager *man,
74                                   struct ttm_resource *res)
75 {
76         struct ttm_mock_manager *manager = to_mock_mgr(man);
77         struct ttm_mock_resource *mock_res = to_mock_mgr_resource(res);
78         struct drm_buddy *mm = &manager->mm;
79
80         mutex_lock(&manager->lock);
81         drm_buddy_free_list(mm, &mock_res->blocks, 0);
82         mutex_unlock(&manager->lock);
83
84         ttm_resource_fini(man, res);
85         kfree(mock_res);
86 }
87
88 static const struct ttm_resource_manager_func ttm_mock_manager_funcs = {
89         .alloc = ttm_mock_manager_alloc,
90         .free = ttm_mock_manager_free,
91 };
92
93 int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
94 {
95         struct ttm_mock_manager *manager;
96         struct ttm_resource_manager *base;
97         int err;
98
99         manager = kzalloc(sizeof(*manager), GFP_KERNEL);
100         if (!manager)
101                 return -ENOMEM;
102
103         mutex_init(&manager->lock);
104
105         err = drm_buddy_init(&manager->mm, size, PAGE_SIZE);
106
107         if (err) {
108                 kfree(manager);
109                 return err;
110         }
111
112         manager->default_page_size = PAGE_SIZE;
113         base = &manager->man;
114         base->func = &ttm_mock_manager_funcs;
115         base->use_tt = true;
116
117         ttm_resource_manager_init(base, bdev, size);
118         ttm_set_driver_manager(bdev, mem_type, base);
119         ttm_resource_manager_set_used(base, true);
120
121         return 0;
122 }
123 EXPORT_SYMBOL_GPL(ttm_mock_manager_init);
124
125 void ttm_mock_manager_fini(struct ttm_device *bdev, u32 mem_type)
126 {
127         struct ttm_resource_manager *man;
128         struct ttm_mock_manager *mock_man;
129         int err;
130
131         man = ttm_manager_type(bdev, mem_type);
132         mock_man = to_mock_mgr(man);
133
134         err = ttm_resource_manager_evict_all(bdev, man);
135         if (err)
136                 return;
137
138         ttm_resource_manager_set_used(man, false);
139
140         mutex_lock(&mock_man->lock);
141         drm_buddy_fini(&mock_man->mm);
142         mutex_unlock(&mock_man->lock);
143
144         ttm_set_driver_manager(bdev, mem_type, NULL);
145 }
146 EXPORT_SYMBOL_GPL(ttm_mock_manager_fini);
147
148 static int ttm_bad_manager_alloc(struct ttm_resource_manager *man,
149                                  struct ttm_buffer_object *bo,
150                                  const struct ttm_place *place,
151                                  struct ttm_resource **res)
152 {
153         return -ENOSPC;
154 }
155
156 static int ttm_busy_manager_alloc(struct ttm_resource_manager *man,
157                                   struct ttm_buffer_object *bo,
158                                   const struct ttm_place *place,
159                                   struct ttm_resource **res)
160 {
161         return -EBUSY;
162 }
163
164 static void ttm_bad_manager_free(struct ttm_resource_manager *man,
165                                  struct ttm_resource *res)
166 {
167 }
168
169 static bool ttm_bad_manager_compatible(struct ttm_resource_manager *man,
170                                        struct ttm_resource *res,
171                                        const struct ttm_place *place,
172                                        size_t size)
173 {
174         return true;
175 }
176
177 static const struct ttm_resource_manager_func ttm_bad_manager_funcs = {
178         .alloc = ttm_bad_manager_alloc,
179         .free = ttm_bad_manager_free,
180         .compatible = ttm_bad_manager_compatible
181 };
182
183 static const struct ttm_resource_manager_func ttm_bad_busy_manager_funcs = {
184         .alloc = ttm_busy_manager_alloc,
185         .free = ttm_bad_manager_free,
186         .compatible = ttm_bad_manager_compatible
187 };
188
189 int ttm_bad_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
190 {
191         struct ttm_resource_manager *man;
192
193         man = kzalloc(sizeof(*man), GFP_KERNEL);
194         if (!man)
195                 return -ENOMEM;
196
197         man->func = &ttm_bad_manager_funcs;
198
199         ttm_resource_manager_init(man, bdev, size);
200         ttm_set_driver_manager(bdev, mem_type, man);
201         ttm_resource_manager_set_used(man, true);
202
203         return 0;
204 }
205 EXPORT_SYMBOL_GPL(ttm_bad_manager_init);
206
207 int ttm_busy_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size)
208 {
209         struct ttm_resource_manager *man;
210
211         ttm_bad_manager_init(bdev, mem_type, size);
212         man = ttm_manager_type(bdev, mem_type);
213
214         man->func = &ttm_bad_busy_manager_funcs;
215
216         return 0;
217 }
218 EXPORT_SYMBOL_GPL(ttm_busy_manager_init);
219
220 void ttm_bad_manager_fini(struct ttm_device *bdev, uint32_t mem_type)
221 {
222         struct ttm_resource_manager *man;
223
224         man = ttm_manager_type(bdev, mem_type);
225
226         ttm_resource_manager_set_used(man, false);
227         ttm_set_driver_manager(bdev, mem_type, NULL);
228
229         kfree(man);
230 }
231 EXPORT_SYMBOL_GPL(ttm_bad_manager_fini);
232
233 MODULE_DESCRIPTION("KUnit tests for ttm with mock resource managers");
234 MODULE_LICENSE("GPL and additional rights");
This page took 0.043204 seconds and 4 git commands to generate.