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 <linux/dma-resv.h>
  6#include <linux/kthread.h>
  7#include <linux/delay.h>
  8#include <linux/timer.h>
  9#include <linux/jiffies.h>
 10#include <linux/mutex.h>
 11#include <linux/ww_mutex.h>
 12
 13#include <drm/ttm/ttm_resource.h>
 14#include <drm/ttm/ttm_placement.h>
 15#include <drm/ttm/ttm_tt.h>
 16
 17#include "ttm_kunit_helpers.h"
 18
 19#define BO_SIZE		SZ_8K
 20
 21#ifdef CONFIG_PREEMPT_RT
 22#define ww_mutex_base_lock(b)			rt_mutex_lock(b)
 23#else
 24#define ww_mutex_base_lock(b)			mutex_lock(b)
 25#endif
 26
 27struct ttm_bo_test_case {
 28	const char *description;
 29	bool interruptible;
 30	bool no_wait;
 31};
 32
 33static const struct ttm_bo_test_case ttm_bo_reserved_cases[] = {
 34	{
 35		.description = "Cannot be interrupted and sleeps",
 36		.interruptible = false,
 37		.no_wait = false,
 38	},
 39	{
 40		.description = "Cannot be interrupted, locks straight away",
 41		.interruptible = false,
 42		.no_wait = true,
 43	},
 44	{
 45		.description = "Can be interrupted, sleeps",
 46		.interruptible = true,
 47		.no_wait = false,
 48	},
 49};
 50
 51static void ttm_bo_init_case_desc(const struct ttm_bo_test_case *t,
 52				  char *desc)
 53{
 54	strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
 55}
 56
 57KUNIT_ARRAY_PARAM(ttm_bo_reserve, ttm_bo_reserved_cases, ttm_bo_init_case_desc);
 58
 59static void ttm_bo_reserve_optimistic_no_ticket(struct kunit *test)
 60{
 61	const struct ttm_bo_test_case *params = test->param_value;
 62	struct ttm_buffer_object *bo;
 63	int err;
 64
 65	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
 66
 67	err = ttm_bo_reserve(bo, params->interruptible, params->no_wait, NULL);
 68	KUNIT_ASSERT_EQ(test, err, 0);
 69
 70	dma_resv_unlock(bo->base.resv);
 71}
 72
 73static void ttm_bo_reserve_locked_no_sleep(struct kunit *test)
 74{
 75	struct ttm_buffer_object *bo;
 76	bool interruptible = false;
 77	bool no_wait = true;
 78	int err;
 79
 80	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
 81
 82	/* Let's lock it beforehand */
 83	dma_resv_lock(bo->base.resv, NULL);
 84
 85	err = ttm_bo_reserve(bo, interruptible, no_wait, NULL);
 86	dma_resv_unlock(bo->base.resv);
 87
 88	KUNIT_ASSERT_EQ(test, err, -EBUSY);
 89}
 90
 91static void ttm_bo_reserve_no_wait_ticket(struct kunit *test)
 92{
 93	struct ttm_buffer_object *bo;
 94	struct ww_acquire_ctx ctx;
 95	bool interruptible = false;
 96	bool no_wait = true;
 97	int err;
 98
 99	ww_acquire_init(&ctx, &reservation_ww_class);
100
101	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
102
103	err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
104	KUNIT_ASSERT_EQ(test, err, -EBUSY);
105
106	ww_acquire_fini(&ctx);
107}
108
109static void ttm_bo_reserve_double_resv(struct kunit *test)
110{
111	struct ttm_buffer_object *bo;
112	struct ww_acquire_ctx ctx;
113	bool interruptible = false;
114	bool no_wait = false;
115	int err;
116
117	ww_acquire_init(&ctx, &reservation_ww_class);
118
119	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
120
121	err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
122	KUNIT_ASSERT_EQ(test, err, 0);
123
124	err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
125
126	dma_resv_unlock(bo->base.resv);
127	ww_acquire_fini(&ctx);
128
129	KUNIT_ASSERT_EQ(test, err, -EALREADY);
130}
131
132/*
133 * A test case heavily inspired by ww_test_edeadlk_normal(). It injects
134 * a deadlock by manipulating the sequence number of the context that holds
135 * dma_resv lock of bo2 so the other context is "wounded" and has to back off
136 * (indicated by -EDEADLK). The subtest checks if ttm_bo_reserve() properly
137 * propagates that error.
138 */
139static void ttm_bo_reserve_deadlock(struct kunit *test)
140{
141	struct ttm_buffer_object *bo1, *bo2;
142	struct ww_acquire_ctx ctx1, ctx2;
143	bool interruptible = false;
144	bool no_wait = false;
145	int err;
146
147	bo1 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
148	bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
149
150	ww_acquire_init(&ctx1, &reservation_ww_class);
151	ww_mutex_base_lock(&bo2->base.resv->lock.base);
152
153	/* The deadlock will be caught by WW mutex, don't warn about it */
154	lock_release(&bo2->base.resv->lock.base.dep_map, 1);
155
156	bo2->base.resv->lock.ctx = &ctx2;
157	ctx2 = ctx1;
158	ctx2.stamp--; /* Make the context holding the lock younger */
159
160	err = ttm_bo_reserve(bo1, interruptible, no_wait, &ctx1);
161	KUNIT_ASSERT_EQ(test, err, 0);
162
163	err = ttm_bo_reserve(bo2, interruptible, no_wait, &ctx1);
164	KUNIT_ASSERT_EQ(test, err, -EDEADLK);
165
166	dma_resv_unlock(bo1->base.resv);
167	ww_acquire_fini(&ctx1);
168}
169
170#if IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST)
171struct signal_timer {
172	struct timer_list timer;
173	struct ww_acquire_ctx *ctx;
174};
175
176static void signal_for_ttm_bo_reserve(struct timer_list *t)
177{
178	struct signal_timer *s_timer = from_timer(s_timer, t, timer);
179	struct task_struct *task = s_timer->ctx->task;
180
181	do_send_sig_info(SIGTERM, SEND_SIG_PRIV, task, PIDTYPE_PID);
182}
183
184static int threaded_ttm_bo_reserve(void *arg)
185{
186	struct ttm_buffer_object *bo = arg;
187	struct signal_timer s_timer;
188	struct ww_acquire_ctx ctx;
189	bool interruptible = true;
190	bool no_wait = false;
191	int err;
192
193	ww_acquire_init(&ctx, &reservation_ww_class);
194
195	/* Prepare a signal that will interrupt the reservation attempt */
196	timer_setup_on_stack(&s_timer.timer, &signal_for_ttm_bo_reserve, 0);
197	s_timer.ctx = &ctx;
198
199	mod_timer(&s_timer.timer, msecs_to_jiffies(100));
200
201	err = ttm_bo_reserve(bo, interruptible, no_wait, &ctx);
202
203	timer_delete_sync(&s_timer.timer);
204	destroy_timer_on_stack(&s_timer.timer);
205
206	ww_acquire_fini(&ctx);
207
208	return err;
209}
210
211static void ttm_bo_reserve_interrupted(struct kunit *test)
212{
213	struct ttm_buffer_object *bo;
214	struct task_struct *task;
215	int err;
216
217	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
218
219	task = kthread_create(threaded_ttm_bo_reserve, bo, "ttm-bo-reserve");
220
221	if (IS_ERR(task))
222		KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n");
223
224	/* Take a lock so the threaded reserve has to wait */
225	mutex_lock(&bo->base.resv->lock.base);
226
227	wake_up_process(task);
228	msleep(20);
229	err = kthread_stop(task);
230
231	mutex_unlock(&bo->base.resv->lock.base);
232
233	KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS);
234}
235#endif /* IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST) */
236
237static void ttm_bo_unreserve_basic(struct kunit *test)
238{
239	struct ttm_test_devices *priv = test->priv;
240	struct ttm_buffer_object *bo;
241	struct ttm_device *ttm_dev;
242	struct ttm_resource *res1, *res2;
243	struct ttm_place *place;
244	struct ttm_resource_manager *man;
245	unsigned int bo_prio = TTM_MAX_BO_PRIORITY - 1;
246	u32 mem_type = TTM_PL_SYSTEM;
247	int err;
248
249	place = ttm_place_kunit_init(test, mem_type, 0);
250
251	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
252	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
253
254	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
255	KUNIT_ASSERT_EQ(test, err, 0);
256	priv->ttm_dev = ttm_dev;
257
258	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
259	bo->priority = bo_prio;
260
261	err = ttm_resource_alloc(bo, place, &res1);
262	KUNIT_ASSERT_EQ(test, err, 0);
263
264	bo->resource = res1;
265
266	/* Add a dummy resource to populate LRU */
267	ttm_resource_alloc(bo, place, &res2);
268
269	dma_resv_lock(bo->base.resv, NULL);
270	ttm_bo_unreserve(bo);
271
272	man = ttm_manager_type(priv->ttm_dev, mem_type);
273	KUNIT_ASSERT_EQ(test,
274			list_is_last(&res1->lru.link, &man->lru[bo->priority]), 1);
275
276	ttm_resource_free(bo, &res2);
277	ttm_resource_free(bo, &res1);
278}
279
280static void ttm_bo_unreserve_pinned(struct kunit *test)
281{
282	struct ttm_test_devices *priv = test->priv;
283	struct ttm_buffer_object *bo;
284	struct ttm_device *ttm_dev;
285	struct ttm_resource *res1, *res2;
286	struct ttm_place *place;
287	u32 mem_type = TTM_PL_SYSTEM;
288	int err;
289
290	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
291	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
292
293	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
294	KUNIT_ASSERT_EQ(test, err, 0);
295	priv->ttm_dev = ttm_dev;
296
297	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
298	place = ttm_place_kunit_init(test, mem_type, 0);
299
300	dma_resv_lock(bo->base.resv, NULL);
301	ttm_bo_pin(bo);
302
303	err = ttm_resource_alloc(bo, place, &res1);
304	KUNIT_ASSERT_EQ(test, err, 0);
305	bo->resource = res1;
306
307	/* Add a dummy resource to the pinned list */
308	err = ttm_resource_alloc(bo, place, &res2);
309	KUNIT_ASSERT_EQ(test, err, 0);
310	KUNIT_ASSERT_EQ(test,
311			list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1);
312
313	ttm_bo_unreserve(bo);
314	KUNIT_ASSERT_EQ(test,
315			list_is_last(&res1->lru.link, &priv->ttm_dev->unevictable), 1);
316
317	ttm_resource_free(bo, &res1);
318	ttm_resource_free(bo, &res2);
319}
320
321static void ttm_bo_unreserve_bulk(struct kunit *test)
322{
323	struct ttm_test_devices *priv = test->priv;
324	struct ttm_lru_bulk_move lru_bulk_move;
325	struct ttm_lru_bulk_move_pos *pos;
326	struct ttm_buffer_object *bo1, *bo2;
327	struct ttm_resource *res1, *res2;
328	struct ttm_device *ttm_dev;
329	struct ttm_place *place;
330	struct dma_resv *resv;
331	u32 mem_type = TTM_PL_SYSTEM;
332	unsigned int bo_priority = 0;
333	int err;
334
335	ttm_lru_bulk_move_init(&lru_bulk_move);
336
337	place = ttm_place_kunit_init(test, mem_type, 0);
338
339	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
340	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
341
342	resv = kunit_kzalloc(test, sizeof(*resv), GFP_KERNEL);
343	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
344
345	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
346	KUNIT_ASSERT_EQ(test, err, 0);
347	priv->ttm_dev = ttm_dev;
348
349	dma_resv_init(resv);
350
351	bo1 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, resv);
352	bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE, resv);
353
354	dma_resv_lock(bo1->base.resv, NULL);
355	ttm_bo_set_bulk_move(bo1, &lru_bulk_move);
356	dma_resv_unlock(bo1->base.resv);
357
358	err = ttm_resource_alloc(bo1, place, &res1);
359	KUNIT_ASSERT_EQ(test, err, 0);
360	bo1->resource = res1;
361
362	dma_resv_lock(bo2->base.resv, NULL);
363	ttm_bo_set_bulk_move(bo2, &lru_bulk_move);
364	dma_resv_unlock(bo2->base.resv);
365
366	err = ttm_resource_alloc(bo2, place, &res2);
367	KUNIT_ASSERT_EQ(test, err, 0);
368	bo2->resource = res2;
369
370	ttm_bo_reserve(bo1, false, false, NULL);
371	ttm_bo_unreserve(bo1);
372
373	pos = &lru_bulk_move.pos[mem_type][bo_priority];
374	KUNIT_ASSERT_PTR_EQ(test, res1, pos->last);
375
376	ttm_resource_free(bo1, &res1);
377	ttm_resource_free(bo2, &res2);
378
379	dma_resv_fini(resv);
380}
381
382static void ttm_bo_put_basic(struct kunit *test)
383{
384	struct ttm_test_devices *priv = test->priv;
385	struct ttm_buffer_object *bo;
386	struct ttm_resource *res;
387	struct ttm_device *ttm_dev;
388	struct ttm_place *place;
389	u32 mem_type = TTM_PL_SYSTEM;
390	int err;
391
392	place = ttm_place_kunit_init(test, mem_type, 0);
393
394	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
395	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
396
397	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
398	KUNIT_ASSERT_EQ(test, err, 0);
399	priv->ttm_dev = ttm_dev;
400
401	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
402	bo->type = ttm_bo_type_device;
403
404	err = ttm_resource_alloc(bo, place, &res);
405	KUNIT_ASSERT_EQ(test, err, 0);
406	bo->resource = res;
407
408	dma_resv_lock(bo->base.resv, NULL);
409	err = ttm_tt_create(bo, false);
410	dma_resv_unlock(bo->base.resv);
411	KUNIT_EXPECT_EQ(test, err, 0);
412
413	ttm_bo_put(bo);
414}
415
416static const char *mock_name(struct dma_fence *f)
417{
418	return "kunit-ttm-bo-put";
419}
420
421static const struct dma_fence_ops mock_fence_ops = {
422	.get_driver_name = mock_name,
423	.get_timeline_name = mock_name,
424};
425
426static void ttm_bo_put_shared_resv(struct kunit *test)
427{
428	struct ttm_test_devices *priv = test->priv;
429	struct ttm_buffer_object *bo;
430	struct dma_resv *external_resv;
431	struct dma_fence *fence;
432	/* A dummy DMA fence lock */
433	spinlock_t fence_lock;
434	struct ttm_device *ttm_dev;
435	int err;
436
437	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
438	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
439
440	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
441	KUNIT_ASSERT_EQ(test, err, 0);
442	priv->ttm_dev = ttm_dev;
443
444	external_resv = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
445	KUNIT_ASSERT_NOT_NULL(test, external_resv);
446
447	dma_resv_init(external_resv);
448
449	fence = kunit_kzalloc(test, sizeof(*fence), GFP_KERNEL);
450	KUNIT_ASSERT_NOT_NULL(test, fence);
451
452	spin_lock_init(&fence_lock);
453	dma_fence_init(fence, &mock_fence_ops, &fence_lock, 0, 0);
454
455	dma_resv_lock(external_resv, NULL);
456	dma_resv_reserve_fences(external_resv, 1);
457	dma_resv_add_fence(external_resv, fence, DMA_RESV_USAGE_BOOKKEEP);
458	dma_resv_unlock(external_resv);
459
460	dma_fence_signal(fence);
461
462	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
463	bo->type = ttm_bo_type_device;
464	bo->base.resv = external_resv;
465
466	ttm_bo_put(bo);
467}
468
469static void ttm_bo_pin_basic(struct kunit *test)
470{
471	struct ttm_test_devices *priv = test->priv;
472	struct ttm_buffer_object *bo;
473	struct ttm_device *ttm_dev;
474	unsigned int no_pins = 3;
475	int err;
476
477	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
478	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
479
480	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
481	KUNIT_ASSERT_EQ(test, err, 0);
482	priv->ttm_dev = ttm_dev;
483
484	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
485
486	for (int i = 0; i < no_pins; i++) {
487		dma_resv_lock(bo->base.resv, NULL);
488		ttm_bo_pin(bo);
489		dma_resv_unlock(bo->base.resv);
490	}
491
492	KUNIT_ASSERT_EQ(test, bo->pin_count, no_pins);
493}
494
495static void ttm_bo_pin_unpin_resource(struct kunit *test)
496{
497	struct ttm_test_devices *priv = test->priv;
498	struct ttm_lru_bulk_move lru_bulk_move;
499	struct ttm_lru_bulk_move_pos *pos;
500	struct ttm_buffer_object *bo;
501	struct ttm_resource *res;
502	struct ttm_device *ttm_dev;
503	struct ttm_place *place;
504	u32 mem_type = TTM_PL_SYSTEM;
505	unsigned int bo_priority = 0;
506	int err;
507
508	ttm_lru_bulk_move_init(&lru_bulk_move);
509
510	place = ttm_place_kunit_init(test, mem_type, 0);
511
512	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
513	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
514
515	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
516	KUNIT_ASSERT_EQ(test, err, 0);
517	priv->ttm_dev = ttm_dev;
518
519	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
520
521	err = ttm_resource_alloc(bo, place, &res);
522	KUNIT_ASSERT_EQ(test, err, 0);
523	bo->resource = res;
524
525	dma_resv_lock(bo->base.resv, NULL);
526	ttm_bo_set_bulk_move(bo, &lru_bulk_move);
527	ttm_bo_pin(bo);
528	dma_resv_unlock(bo->base.resv);
529
530	pos = &lru_bulk_move.pos[mem_type][bo_priority];
531
532	KUNIT_ASSERT_EQ(test, bo->pin_count, 1);
533	KUNIT_ASSERT_NULL(test, pos->first);
534	KUNIT_ASSERT_NULL(test, pos->last);
535
536	dma_resv_lock(bo->base.resv, NULL);
537	ttm_bo_unpin(bo);
538	dma_resv_unlock(bo->base.resv);
539
540	KUNIT_ASSERT_PTR_EQ(test, res, pos->last);
541	KUNIT_ASSERT_EQ(test, bo->pin_count, 0);
542
543	ttm_resource_free(bo, &res);
544}
545
546static void ttm_bo_multiple_pin_one_unpin(struct kunit *test)
547{
548	struct ttm_test_devices *priv = test->priv;
549	struct ttm_lru_bulk_move lru_bulk_move;
550	struct ttm_lru_bulk_move_pos *pos;
551	struct ttm_buffer_object *bo;
552	struct ttm_resource *res;
553	struct ttm_device *ttm_dev;
554	struct ttm_place *place;
555	u32 mem_type = TTM_PL_SYSTEM;
556	unsigned int bo_priority = 0;
557	int err;
558
559	ttm_lru_bulk_move_init(&lru_bulk_move);
560
561	place = ttm_place_kunit_init(test, mem_type, 0);
562
563	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
564	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
565
566	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
567	KUNIT_ASSERT_EQ(test, err, 0);
568	priv->ttm_dev = ttm_dev;
569
570	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
571
572	err = ttm_resource_alloc(bo, place, &res);
573	KUNIT_ASSERT_EQ(test, err, 0);
574	bo->resource = res;
575
576	dma_resv_lock(bo->base.resv, NULL);
577	ttm_bo_set_bulk_move(bo, &lru_bulk_move);
578
579	/* Multiple pins */
580	ttm_bo_pin(bo);
581	ttm_bo_pin(bo);
582
583	dma_resv_unlock(bo->base.resv);
584
585	pos = &lru_bulk_move.pos[mem_type][bo_priority];
586
587	KUNIT_ASSERT_EQ(test, bo->pin_count, 2);
588	KUNIT_ASSERT_NULL(test, pos->first);
589	KUNIT_ASSERT_NULL(test, pos->last);
590
591	dma_resv_lock(bo->base.resv, NULL);
592	ttm_bo_unpin(bo);
593	dma_resv_unlock(bo->base.resv);
594
595	KUNIT_ASSERT_EQ(test, bo->pin_count, 1);
596	KUNIT_ASSERT_NULL(test, pos->first);
597	KUNIT_ASSERT_NULL(test, pos->last);
598
599	dma_resv_lock(bo->base.resv, NULL);
600	ttm_bo_unpin(bo);
601	dma_resv_unlock(bo->base.resv);
602
603	ttm_resource_free(bo, &res);
604}
605
606static struct kunit_case ttm_bo_test_cases[] = {
607	KUNIT_CASE_PARAM(ttm_bo_reserve_optimistic_no_ticket,
608			 ttm_bo_reserve_gen_params),
609	KUNIT_CASE(ttm_bo_reserve_locked_no_sleep),
610	KUNIT_CASE(ttm_bo_reserve_no_wait_ticket),
611	KUNIT_CASE(ttm_bo_reserve_double_resv),
612#if IS_BUILTIN(CONFIG_DRM_TTM_KUNIT_TEST)
613	KUNIT_CASE(ttm_bo_reserve_interrupted),
614#endif
615	KUNIT_CASE(ttm_bo_reserve_deadlock),
616	KUNIT_CASE(ttm_bo_unreserve_basic),
617	KUNIT_CASE(ttm_bo_unreserve_pinned),
618	KUNIT_CASE(ttm_bo_unreserve_bulk),
619	KUNIT_CASE(ttm_bo_put_basic),
620	KUNIT_CASE(ttm_bo_put_shared_resv),
621	KUNIT_CASE(ttm_bo_pin_basic),
622	KUNIT_CASE(ttm_bo_pin_unpin_resource),
623	KUNIT_CASE(ttm_bo_multiple_pin_one_unpin),
624	{}
625};
626
627static struct kunit_suite ttm_bo_test_suite = {
628	.name = "ttm_bo",
629	.init = ttm_test_devices_init,
630	.exit = ttm_test_devices_fini,
631	.test_cases = ttm_bo_test_cases,
632};
633
634kunit_test_suites(&ttm_bo_test_suite);
635
636MODULE_DESCRIPTION("KUnit tests for ttm_bo APIs");
637MODULE_LICENSE("GPL and additional rights");