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#include <drm/ttm/ttm_device.h>
7#include <drm/ttm/ttm_placement.h>
8
9#include "ttm_mock_manager.h"
10
11static inline struct ttm_mock_manager *
12to_mock_mgr(struct ttm_resource_manager *man)
13{
14 return container_of(man, struct ttm_mock_manager, man);
15}
16
17static inline struct ttm_mock_resource *
18to_mock_mgr_resource(struct ttm_resource *res)
19{
20 return container_of(res, struct ttm_mock_resource, base);
21}
22
23static 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
65error_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
73static 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
88static const struct ttm_resource_manager_func ttm_mock_manager_funcs = {
89 .alloc = ttm_mock_manager_alloc,
90 .free = ttm_mock_manager_free,
91};
92
93int 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}
123EXPORT_SYMBOL_GPL(ttm_mock_manager_init);
124
125void 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}
146EXPORT_SYMBOL_GPL(ttm_mock_manager_fini);
147
148static 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
156static 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
164static void ttm_bad_manager_free(struct ttm_resource_manager *man,
165 struct ttm_resource *res)
166{
167}
168
169static 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
177static 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
183static 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
189int 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}
205EXPORT_SYMBOL_GPL(ttm_bad_manager_init);
206
207int 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}
218EXPORT_SYMBOL_GPL(ttm_busy_manager_init);
219
220void 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}
231EXPORT_SYMBOL_GPL(ttm_bad_manager_fini);
232
233MODULE_DESCRIPTION("KUnit tests for ttm with mock resource managers");
234MODULE_LICENSE("GPL and additional rights");