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#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");