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