1 // SPDX-License-Identifier: GPL-2.0 AND MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 #include <linux/delay.h> 6 #include <linux/kthread.h> 7 8 #include <drm/ttm/ttm_resource.h> 9 #include <drm/ttm/ttm_placement.h> 10 #include <drm/ttm/ttm_tt.h> 11 12 #include "ttm_kunit_helpers.h" 13 #include "ttm_mock_manager.h" 14 15 #define BO_SIZE SZ_4K 16 #define MANAGER_SIZE SZ_1M 17 18 static struct spinlock fence_lock; 19 20 struct ttm_bo_validate_test_case { 21 const char *description; 22 enum ttm_bo_type bo_type; 23 u32 mem_type; 24 bool with_ttm; 25 bool no_gpu_wait; 26 }; 27 28 static struct ttm_placement *ttm_placement_kunit_init(struct kunit *test, 29 struct ttm_place *places, 30 unsigned int num_places) 31 { 32 struct ttm_placement *placement; 33 34 placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL); 35 KUNIT_ASSERT_NOT_NULL(test, placement); 36 37 placement->num_placement = num_places; 38 placement->placement = places; 39 40 return placement; 41 } 42 43 static const char *fence_name(struct dma_fence *f) 44 { 45 return "ttm-bo-validate-fence"; 46 } 47 48 static const struct dma_fence_ops fence_ops = { 49 .get_driver_name = fence_name, 50 .get_timeline_name = fence_name, 51 }; 52 53 static struct dma_fence *alloc_mock_fence(struct kunit *test) 54 { 55 struct dma_fence *fence; 56 57 fence = kunit_kzalloc(test, sizeof(*fence), GFP_KERNEL); 58 KUNIT_ASSERT_NOT_NULL(test, fence); 59 60 dma_fence_init(fence, &fence_ops, &fence_lock, 0, 0); 61 62 return fence; 63 } 64 65 static void dma_resv_kunit_active_fence_init(struct kunit *test, 66 struct dma_resv *resv, 67 enum dma_resv_usage usage) 68 { 69 struct dma_fence *fence; 70 71 fence = alloc_mock_fence(test); 72 dma_fence_enable_sw_signaling(fence); 73 74 dma_resv_lock(resv, NULL); 75 dma_resv_reserve_fences(resv, 1); 76 dma_resv_add_fence(resv, fence, usage); 77 dma_resv_unlock(resv); 78 } 79 80 static void ttm_bo_validate_case_desc(const struct ttm_bo_validate_test_case *t, 81 char *desc) 82 { 83 strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE); 84 } 85 86 static const struct ttm_bo_validate_test_case ttm_bo_type_cases[] = { 87 { 88 .description = "Buffer object for userspace", 89 .bo_type = ttm_bo_type_device, 90 }, 91 { 92 .description = "Kernel buffer object", 93 .bo_type = ttm_bo_type_kernel, 94 }, 95 { 96 .description = "Shared buffer object", 97 .bo_type = ttm_bo_type_sg, 98 }, 99 }; 100 101 KUNIT_ARRAY_PARAM(ttm_bo_types, ttm_bo_type_cases, 102 ttm_bo_validate_case_desc); 103 104 static void ttm_bo_init_reserved_sys_man(struct kunit *test) 105 { 106 const struct ttm_bo_validate_test_case *params = test->param_value; 107 struct ttm_test_devices *priv = test->priv; 108 enum ttm_bo_type bo_type = params->bo_type; 109 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 110 struct ttm_operation_ctx ctx = { }; 111 struct ttm_placement *placement; 112 struct ttm_buffer_object *bo; 113 struct ttm_place *place; 114 int err; 115 116 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 117 KUNIT_ASSERT_NOT_NULL(test, bo); 118 119 place = ttm_place_kunit_init(test, TTM_PL_SYSTEM, 0); 120 placement = ttm_placement_kunit_init(test, place, 1); 121 122 drm_gem_private_object_init(priv->drm, &bo->base, size); 123 124 err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement, 125 PAGE_SIZE, &ctx, NULL, NULL, 126 &dummy_ttm_bo_destroy); 127 dma_resv_unlock(bo->base.resv); 128 129 KUNIT_EXPECT_EQ(test, err, 0); 130 KUNIT_EXPECT_EQ(test, kref_read(&bo->kref), 1); 131 KUNIT_EXPECT_PTR_EQ(test, bo->bdev, priv->ttm_dev); 132 KUNIT_EXPECT_EQ(test, bo->type, bo_type); 133 KUNIT_EXPECT_EQ(test, bo->page_alignment, PAGE_SIZE); 134 KUNIT_EXPECT_PTR_EQ(test, bo->destroy, &dummy_ttm_bo_destroy); 135 KUNIT_EXPECT_EQ(test, bo->pin_count, 0); 136 KUNIT_EXPECT_NULL(test, bo->bulk_move); 137 KUNIT_EXPECT_NOT_NULL(test, bo->ttm); 138 KUNIT_EXPECT_FALSE(test, ttm_tt_is_populated(bo->ttm)); 139 KUNIT_EXPECT_NOT_NULL(test, (void *)bo->base.resv->fences); 140 KUNIT_EXPECT_EQ(test, ctx.bytes_moved, size); 141 142 if (bo_type != ttm_bo_type_kernel) 143 KUNIT_EXPECT_TRUE(test, 144 drm_mm_node_allocated(&bo->base.vma_node.vm_node)); 145 146 ttm_resource_free(bo, &bo->resource); 147 ttm_bo_put(bo); 148 } 149 150 static void ttm_bo_init_reserved_mock_man(struct kunit *test) 151 { 152 const struct ttm_bo_validate_test_case *params = test->param_value; 153 enum ttm_bo_type bo_type = params->bo_type; 154 struct ttm_test_devices *priv = test->priv; 155 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 156 struct ttm_operation_ctx ctx = { }; 157 struct ttm_placement *placement; 158 u32 mem_type = TTM_PL_VRAM; 159 struct ttm_buffer_object *bo; 160 struct ttm_place *place; 161 int err; 162 163 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 164 165 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 166 KUNIT_ASSERT_NOT_NULL(test, bo); 167 168 place = ttm_place_kunit_init(test, mem_type, 0); 169 placement = ttm_placement_kunit_init(test, place, 1); 170 171 drm_gem_private_object_init(priv->drm, &bo->base, size); 172 173 err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement, 174 PAGE_SIZE, &ctx, NULL, NULL, 175 &dummy_ttm_bo_destroy); 176 dma_resv_unlock(bo->base.resv); 177 178 KUNIT_EXPECT_EQ(test, err, 0); 179 KUNIT_EXPECT_EQ(test, kref_read(&bo->kref), 1); 180 KUNIT_EXPECT_PTR_EQ(test, bo->bdev, priv->ttm_dev); 181 KUNIT_EXPECT_EQ(test, bo->type, bo_type); 182 KUNIT_EXPECT_EQ(test, ctx.bytes_moved, size); 183 184 if (bo_type != ttm_bo_type_kernel) 185 KUNIT_EXPECT_TRUE(test, 186 drm_mm_node_allocated(&bo->base.vma_node.vm_node)); 187 188 ttm_resource_free(bo, &bo->resource); 189 ttm_bo_put(bo); 190 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 191 } 192 193 static void ttm_bo_init_reserved_resv(struct kunit *test) 194 { 195 enum ttm_bo_type bo_type = ttm_bo_type_device; 196 struct ttm_test_devices *priv = test->priv; 197 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 198 struct ttm_operation_ctx ctx = { }; 199 struct ttm_placement *placement; 200 struct ttm_buffer_object *bo; 201 struct ttm_place *place; 202 struct dma_resv resv; 203 int err; 204 205 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 206 KUNIT_ASSERT_NOT_NULL(test, bo); 207 208 place = ttm_place_kunit_init(test, TTM_PL_SYSTEM, 0); 209 placement = ttm_placement_kunit_init(test, place, 1); 210 211 drm_gem_private_object_init(priv->drm, &bo->base, size); 212 dma_resv_init(&resv); 213 dma_resv_lock(&resv, NULL); 214 215 err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement, 216 PAGE_SIZE, &ctx, NULL, &resv, 217 &dummy_ttm_bo_destroy); 218 dma_resv_unlock(bo->base.resv); 219 220 KUNIT_EXPECT_EQ(test, err, 0); 221 KUNIT_EXPECT_PTR_EQ(test, bo->base.resv, &resv); 222 223 ttm_resource_free(bo, &bo->resource); 224 ttm_bo_put(bo); 225 } 226 227 static void ttm_bo_validate_basic(struct kunit *test) 228 { 229 const struct ttm_bo_validate_test_case *params = test->param_value; 230 u32 fst_mem = TTM_PL_SYSTEM, snd_mem = TTM_PL_VRAM; 231 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 232 struct ttm_placement *fst_placement, *snd_placement; 233 struct ttm_test_devices *priv = test->priv; 234 struct ttm_place *fst_place, *snd_place; 235 u32 size = ALIGN(SZ_8K, PAGE_SIZE); 236 struct ttm_buffer_object *bo; 237 int err; 238 239 ttm_mock_manager_init(priv->ttm_dev, snd_mem, MANAGER_SIZE); 240 241 fst_place = ttm_place_kunit_init(test, fst_mem, 0); 242 fst_placement = ttm_placement_kunit_init(test, fst_place, 1); 243 244 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 245 KUNIT_ASSERT_NOT_NULL(test, bo); 246 247 drm_gem_private_object_init(priv->drm, &bo->base, size); 248 249 err = ttm_bo_init_reserved(priv->ttm_dev, bo, params->bo_type, 250 fst_placement, PAGE_SIZE, &ctx_init, NULL, 251 NULL, &dummy_ttm_bo_destroy); 252 KUNIT_EXPECT_EQ(test, err, 0); 253 254 snd_place = ttm_place_kunit_init(test, snd_mem, DRM_BUDDY_TOPDOWN_ALLOCATION); 255 snd_placement = ttm_placement_kunit_init(test, snd_place, 1); 256 257 err = ttm_bo_validate(bo, snd_placement, &ctx_val); 258 dma_resv_unlock(bo->base.resv); 259 260 KUNIT_EXPECT_EQ(test, err, 0); 261 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, bo->base.size); 262 KUNIT_EXPECT_NOT_NULL(test, bo->ttm); 263 KUNIT_EXPECT_TRUE(test, ttm_tt_is_populated(bo->ttm)); 264 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, snd_mem); 265 KUNIT_EXPECT_EQ(test, bo->resource->placement, 266 DRM_BUDDY_TOPDOWN_ALLOCATION); 267 268 ttm_bo_put(bo); 269 ttm_mock_manager_fini(priv->ttm_dev, snd_mem); 270 } 271 272 static void ttm_bo_validate_invalid_placement(struct kunit *test) 273 { 274 enum ttm_bo_type bo_type = ttm_bo_type_device; 275 u32 unknown_mem_type = TTM_PL_PRIV + 1; 276 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 277 struct ttm_operation_ctx ctx = { }; 278 struct ttm_placement *placement; 279 struct ttm_buffer_object *bo; 280 struct ttm_place *place; 281 int err; 282 283 place = ttm_place_kunit_init(test, unknown_mem_type, 0); 284 placement = ttm_placement_kunit_init(test, place, 1); 285 286 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 287 bo->type = bo_type; 288 289 ttm_bo_reserve(bo, false, false, NULL); 290 err = ttm_bo_validate(bo, placement, &ctx); 291 dma_resv_unlock(bo->base.resv); 292 293 KUNIT_EXPECT_EQ(test, err, -ENOMEM); 294 295 ttm_bo_put(bo); 296 } 297 298 static void ttm_bo_validate_failed_alloc(struct kunit *test) 299 { 300 enum ttm_bo_type bo_type = ttm_bo_type_device; 301 struct ttm_test_devices *priv = test->priv; 302 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 303 struct ttm_operation_ctx ctx = { }; 304 struct ttm_placement *placement; 305 u32 mem_type = TTM_PL_VRAM; 306 struct ttm_buffer_object *bo; 307 struct ttm_place *place; 308 int err; 309 310 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 311 bo->type = bo_type; 312 313 ttm_bad_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 314 315 place = ttm_place_kunit_init(test, mem_type, 0); 316 placement = ttm_placement_kunit_init(test, place, 1); 317 318 ttm_bo_reserve(bo, false, false, NULL); 319 err = ttm_bo_validate(bo, placement, &ctx); 320 dma_resv_unlock(bo->base.resv); 321 322 KUNIT_EXPECT_EQ(test, err, -ENOMEM); 323 324 ttm_bo_put(bo); 325 ttm_bad_manager_fini(priv->ttm_dev, mem_type); 326 } 327 328 static void ttm_bo_validate_pinned(struct kunit *test) 329 { 330 enum ttm_bo_type bo_type = ttm_bo_type_device; 331 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 332 struct ttm_operation_ctx ctx = { }; 333 u32 mem_type = TTM_PL_SYSTEM; 334 struct ttm_placement *placement; 335 struct ttm_buffer_object *bo; 336 struct ttm_place *place; 337 int err; 338 339 place = ttm_place_kunit_init(test, mem_type, 0); 340 placement = ttm_placement_kunit_init(test, place, 1); 341 342 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 343 bo->type = bo_type; 344 345 ttm_bo_reserve(bo, false, false, NULL); 346 ttm_bo_pin(bo); 347 err = ttm_bo_validate(bo, placement, &ctx); 348 dma_resv_unlock(bo->base.resv); 349 350 KUNIT_EXPECT_EQ(test, err, -EINVAL); 351 352 ttm_bo_reserve(bo, false, false, NULL); 353 ttm_bo_unpin(bo); 354 dma_resv_unlock(bo->base.resv); 355 356 ttm_bo_put(bo); 357 } 358 359 static const struct ttm_bo_validate_test_case ttm_mem_type_cases[] = { 360 { 361 .description = "System manager", 362 .mem_type = TTM_PL_SYSTEM, 363 }, 364 { 365 .description = "VRAM manager", 366 .mem_type = TTM_PL_VRAM, 367 }, 368 }; 369 370 KUNIT_ARRAY_PARAM(ttm_bo_validate_mem, ttm_mem_type_cases, 371 ttm_bo_validate_case_desc); 372 373 static void ttm_bo_validate_same_placement(struct kunit *test) 374 { 375 const struct ttm_bo_validate_test_case *params = test->param_value; 376 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 377 struct ttm_test_devices *priv = test->priv; 378 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 379 struct ttm_placement *placement; 380 struct ttm_buffer_object *bo; 381 struct ttm_place *place; 382 int err; 383 384 place = ttm_place_kunit_init(test, params->mem_type, 0); 385 placement = ttm_placement_kunit_init(test, place, 1); 386 387 if (params->mem_type != TTM_PL_SYSTEM) 388 ttm_mock_manager_init(priv->ttm_dev, params->mem_type, MANAGER_SIZE); 389 390 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 391 KUNIT_ASSERT_NOT_NULL(test, bo); 392 393 drm_gem_private_object_init(priv->drm, &bo->base, size); 394 395 err = ttm_bo_init_reserved(priv->ttm_dev, bo, params->bo_type, 396 placement, PAGE_SIZE, &ctx_init, NULL, 397 NULL, &dummy_ttm_bo_destroy); 398 KUNIT_EXPECT_EQ(test, err, 0); 399 400 err = ttm_bo_validate(bo, placement, &ctx_val); 401 dma_resv_unlock(bo->base.resv); 402 403 KUNIT_EXPECT_EQ(test, err, 0); 404 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, 0); 405 406 ttm_bo_put(bo); 407 408 if (params->mem_type != TTM_PL_SYSTEM) 409 ttm_mock_manager_fini(priv->ttm_dev, params->mem_type); 410 } 411 412 static void ttm_bo_validate_busy_placement(struct kunit *test) 413 { 414 u32 fst_mem = TTM_PL_VRAM, snd_mem = TTM_PL_VRAM + 1; 415 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 416 struct ttm_placement *placement_init, *placement_val; 417 enum ttm_bo_type bo_type = ttm_bo_type_device; 418 struct ttm_test_devices *priv = test->priv; 419 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 420 struct ttm_place *init_place, places[2]; 421 struct ttm_resource_manager *man; 422 struct ttm_buffer_object *bo; 423 int err; 424 425 ttm_bad_manager_init(priv->ttm_dev, fst_mem, MANAGER_SIZE); 426 ttm_mock_manager_init(priv->ttm_dev, snd_mem, MANAGER_SIZE); 427 428 init_place = ttm_place_kunit_init(test, TTM_PL_SYSTEM, 0); 429 placement_init = ttm_placement_kunit_init(test, init_place, 1); 430 431 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 432 KUNIT_ASSERT_NOT_NULL(test, bo); 433 434 drm_gem_private_object_init(priv->drm, &bo->base, size); 435 436 err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement_init, 437 PAGE_SIZE, &ctx_init, NULL, NULL, 438 &dummy_ttm_bo_destroy); 439 KUNIT_EXPECT_EQ(test, err, 0); 440 441 places[0] = (struct ttm_place){ .mem_type = fst_mem, .flags = TTM_PL_FLAG_DESIRED }; 442 places[1] = (struct ttm_place){ .mem_type = snd_mem, .flags = TTM_PL_FLAG_FALLBACK }; 443 placement_val = ttm_placement_kunit_init(test, places, 2); 444 445 err = ttm_bo_validate(bo, placement_val, &ctx_val); 446 dma_resv_unlock(bo->base.resv); 447 448 man = ttm_manager_type(priv->ttm_dev, snd_mem); 449 450 KUNIT_EXPECT_EQ(test, err, 0); 451 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, bo->base.size); 452 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, snd_mem); 453 KUNIT_ASSERT_TRUE(test, list_is_singular(&man->lru[bo->priority])); 454 455 ttm_bo_put(bo); 456 ttm_bad_manager_fini(priv->ttm_dev, fst_mem); 457 ttm_mock_manager_fini(priv->ttm_dev, snd_mem); 458 } 459 460 static void ttm_bo_validate_multihop(struct kunit *test) 461 { 462 const struct ttm_bo_validate_test_case *params = test->param_value; 463 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 464 struct ttm_placement *placement_init, *placement_val; 465 u32 fst_mem = TTM_PL_VRAM, tmp_mem = TTM_PL_TT, final_mem = TTM_PL_SYSTEM; 466 struct ttm_test_devices *priv = test->priv; 467 struct ttm_place *fst_place, *final_place; 468 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 469 struct ttm_buffer_object *bo; 470 int err; 471 472 ttm_mock_manager_init(priv->ttm_dev, fst_mem, MANAGER_SIZE); 473 ttm_mock_manager_init(priv->ttm_dev, tmp_mem, MANAGER_SIZE); 474 475 fst_place = ttm_place_kunit_init(test, fst_mem, 0); 476 placement_init = ttm_placement_kunit_init(test, fst_place, 1); 477 478 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 479 KUNIT_ASSERT_NOT_NULL(test, bo); 480 481 drm_gem_private_object_init(priv->drm, &bo->base, size); 482 483 err = ttm_bo_init_reserved(priv->ttm_dev, bo, params->bo_type, 484 placement_init, PAGE_SIZE, &ctx_init, NULL, 485 NULL, &dummy_ttm_bo_destroy); 486 KUNIT_EXPECT_EQ(test, err, 0); 487 488 final_place = ttm_place_kunit_init(test, final_mem, 0); 489 placement_val = ttm_placement_kunit_init(test, final_place, 1); 490 491 err = ttm_bo_validate(bo, placement_val, &ctx_val); 492 dma_resv_unlock(bo->base.resv); 493 494 KUNIT_EXPECT_EQ(test, err, 0); 495 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size * 2); 496 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, final_mem); 497 498 ttm_bo_put(bo); 499 500 ttm_mock_manager_fini(priv->ttm_dev, fst_mem); 501 ttm_mock_manager_fini(priv->ttm_dev, tmp_mem); 502 } 503 504 static const struct ttm_bo_validate_test_case ttm_bo_no_placement_cases[] = { 505 { 506 .description = "Buffer object in system domain, no page vector", 507 }, 508 { 509 .description = "Buffer object in system domain with an existing page vector", 510 .with_ttm = true, 511 }, 512 }; 513 514 KUNIT_ARRAY_PARAM(ttm_bo_no_placement, ttm_bo_no_placement_cases, 515 ttm_bo_validate_case_desc); 516 517 static void ttm_bo_validate_no_placement_signaled(struct kunit *test) 518 { 519 const struct ttm_bo_validate_test_case *params = test->param_value; 520 enum ttm_bo_type bo_type = ttm_bo_type_device; 521 struct ttm_test_devices *priv = test->priv; 522 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 523 struct ttm_operation_ctx ctx = { }; 524 u32 mem_type = TTM_PL_SYSTEM; 525 struct ttm_resource_manager *man; 526 struct ttm_placement *placement; 527 struct ttm_buffer_object *bo; 528 struct ttm_place *place; 529 struct ttm_tt *old_tt; 530 u32 flags; 531 int err; 532 533 place = ttm_place_kunit_init(test, mem_type, 0); 534 man = ttm_manager_type(priv->ttm_dev, mem_type); 535 536 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 537 bo->type = bo_type; 538 539 if (params->with_ttm) { 540 old_tt = priv->ttm_dev->funcs->ttm_tt_create(bo, 0); 541 ttm_pool_alloc(&priv->ttm_dev->pool, old_tt, &ctx); 542 bo->ttm = old_tt; 543 } 544 545 placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL); 546 KUNIT_ASSERT_NOT_NULL(test, placement); 547 548 ttm_bo_reserve(bo, false, false, NULL); 549 550 err = ttm_resource_alloc(bo, place, &bo->resource, NULL); 551 KUNIT_EXPECT_EQ(test, err, 0); 552 KUNIT_ASSERT_EQ(test, man->usage, size); 553 554 err = ttm_bo_validate(bo, placement, &ctx); 555 ttm_bo_unreserve(bo); 556 557 KUNIT_EXPECT_EQ(test, err, 0); 558 KUNIT_ASSERT_EQ(test, man->usage, 0); 559 KUNIT_ASSERT_NOT_NULL(test, bo->ttm); 560 KUNIT_EXPECT_EQ(test, ctx.bytes_moved, 0); 561 562 if (params->with_ttm) { 563 flags = bo->ttm->page_flags; 564 565 KUNIT_ASSERT_PTR_EQ(test, bo->ttm, old_tt); 566 KUNIT_ASSERT_FALSE(test, flags & TTM_TT_FLAG_PRIV_POPULATED); 567 KUNIT_ASSERT_TRUE(test, flags & TTM_TT_FLAG_ZERO_ALLOC); 568 } 569 570 ttm_bo_put(bo); 571 } 572 573 static int threaded_dma_resv_signal(void *arg) 574 { 575 struct ttm_buffer_object *bo = arg; 576 struct dma_resv *resv = bo->base.resv; 577 struct dma_resv_iter cursor; 578 struct dma_fence *fence; 579 580 dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_BOOKKEEP); 581 dma_resv_for_each_fence_unlocked(&cursor, fence) { 582 dma_fence_signal(fence); 583 } 584 dma_resv_iter_end(&cursor); 585 586 return 0; 587 } 588 589 static void ttm_bo_validate_no_placement_not_signaled(struct kunit *test) 590 { 591 const struct ttm_bo_validate_test_case *params = test->param_value; 592 enum dma_resv_usage usage = DMA_RESV_USAGE_BOOKKEEP; 593 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 594 struct ttm_operation_ctx ctx = { }; 595 u32 mem_type = TTM_PL_SYSTEM; 596 struct ttm_placement *placement; 597 struct ttm_buffer_object *bo; 598 struct task_struct *task; 599 struct ttm_place *place; 600 int err; 601 602 place = ttm_place_kunit_init(test, mem_type, 0); 603 604 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 605 bo->type = params->bo_type; 606 607 err = ttm_resource_alloc(bo, place, &bo->resource, NULL); 608 KUNIT_EXPECT_EQ(test, err, 0); 609 610 placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL); 611 KUNIT_ASSERT_NOT_NULL(test, placement); 612 613 /* Create an active fence to simulate a non-idle resv object */ 614 spin_lock_init(&fence_lock); 615 dma_resv_kunit_active_fence_init(test, bo->base.resv, usage); 616 617 task = kthread_create(threaded_dma_resv_signal, bo, "dma-resv-signal"); 618 if (IS_ERR(task)) 619 KUNIT_FAIL(test, "Couldn't create dma resv signal task\n"); 620 621 wake_up_process(task); 622 ttm_bo_reserve(bo, false, false, NULL); 623 err = ttm_bo_validate(bo, placement, &ctx); 624 ttm_bo_unreserve(bo); 625 626 KUNIT_EXPECT_EQ(test, err, 0); 627 KUNIT_ASSERT_NOT_NULL(test, bo->ttm); 628 KUNIT_ASSERT_NULL(test, bo->resource); 629 KUNIT_ASSERT_NULL(test, bo->bulk_move); 630 KUNIT_EXPECT_EQ(test, ctx.bytes_moved, 0); 631 632 if (bo->type != ttm_bo_type_sg) 633 KUNIT_ASSERT_PTR_EQ(test, bo->base.resv, &bo->base._resv); 634 635 /* Make sure we have an idle object at this point */ 636 dma_resv_wait_timeout(bo->base.resv, usage, false, MAX_SCHEDULE_TIMEOUT); 637 638 ttm_bo_put(bo); 639 } 640 641 static void ttm_bo_validate_move_fence_signaled(struct kunit *test) 642 { 643 enum ttm_bo_type bo_type = ttm_bo_type_device; 644 struct ttm_test_devices *priv = test->priv; 645 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 646 struct ttm_operation_ctx ctx = { }; 647 u32 mem_type = TTM_PL_SYSTEM; 648 struct ttm_resource_manager *man; 649 struct ttm_placement *placement; 650 struct ttm_buffer_object *bo; 651 struct ttm_place *place; 652 int err; 653 654 man = ttm_manager_type(priv->ttm_dev, mem_type); 655 man->move = dma_fence_get_stub(); 656 657 bo = ttm_bo_kunit_init(test, test->priv, size, NULL); 658 bo->type = bo_type; 659 660 place = ttm_place_kunit_init(test, mem_type, 0); 661 placement = ttm_placement_kunit_init(test, place, 1); 662 663 ttm_bo_reserve(bo, false, false, NULL); 664 err = ttm_bo_validate(bo, placement, &ctx); 665 ttm_bo_unreserve(bo); 666 667 KUNIT_EXPECT_EQ(test, err, 0); 668 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type); 669 KUNIT_EXPECT_EQ(test, ctx.bytes_moved, size); 670 671 ttm_bo_put(bo); 672 dma_fence_put(man->move); 673 } 674 675 static const struct ttm_bo_validate_test_case ttm_bo_validate_wait_cases[] = { 676 { 677 .description = "Waits for GPU", 678 .no_gpu_wait = false, 679 }, 680 { 681 .description = "Tries to lock straight away", 682 .no_gpu_wait = true, 683 }, 684 }; 685 686 KUNIT_ARRAY_PARAM(ttm_bo_validate_wait, ttm_bo_validate_wait_cases, 687 ttm_bo_validate_case_desc); 688 689 static int threaded_fence_signal(void *arg) 690 { 691 struct dma_fence *fence = arg; 692 693 msleep(20); 694 695 return dma_fence_signal(fence); 696 } 697 698 static void ttm_bo_validate_move_fence_not_signaled(struct kunit *test) 699 { 700 const struct ttm_bo_validate_test_case *params = test->param_value; 701 struct ttm_operation_ctx ctx_init = { }, 702 ctx_val = { .no_wait_gpu = params->no_gpu_wait }; 703 u32 fst_mem = TTM_PL_VRAM, snd_mem = TTM_PL_VRAM + 1; 704 struct ttm_placement *placement_init, *placement_val; 705 enum ttm_bo_type bo_type = ttm_bo_type_device; 706 struct ttm_test_devices *priv = test->priv; 707 u32 size = ALIGN(BO_SIZE, PAGE_SIZE); 708 struct ttm_place *init_place, places[2]; 709 struct ttm_resource_manager *man; 710 struct ttm_buffer_object *bo; 711 struct task_struct *task; 712 int err; 713 714 init_place = ttm_place_kunit_init(test, TTM_PL_SYSTEM, 0); 715 placement_init = ttm_placement_kunit_init(test, init_place, 1); 716 717 bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); 718 KUNIT_ASSERT_NOT_NULL(test, bo); 719 720 drm_gem_private_object_init(priv->drm, &bo->base, size); 721 722 err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement_init, 723 PAGE_SIZE, &ctx_init, NULL, NULL, 724 &dummy_ttm_bo_destroy); 725 KUNIT_EXPECT_EQ(test, err, 0); 726 727 ttm_mock_manager_init(priv->ttm_dev, fst_mem, MANAGER_SIZE); 728 ttm_mock_manager_init(priv->ttm_dev, snd_mem, MANAGER_SIZE); 729 730 places[0] = (struct ttm_place){ .mem_type = fst_mem, .flags = TTM_PL_FLAG_DESIRED }; 731 places[1] = (struct ttm_place){ .mem_type = snd_mem, .flags = TTM_PL_FLAG_FALLBACK }; 732 placement_val = ttm_placement_kunit_init(test, places, 2); 733 734 spin_lock_init(&fence_lock); 735 man = ttm_manager_type(priv->ttm_dev, fst_mem); 736 man->move = alloc_mock_fence(test); 737 738 task = kthread_create(threaded_fence_signal, man->move, "move-fence-signal"); 739 if (IS_ERR(task)) 740 KUNIT_FAIL(test, "Couldn't create move fence signal task\n"); 741 742 wake_up_process(task); 743 err = ttm_bo_validate(bo, placement_val, &ctx_val); 744 dma_resv_unlock(bo->base.resv); 745 746 dma_fence_wait_timeout(man->move, false, MAX_SCHEDULE_TIMEOUT); 747 748 KUNIT_EXPECT_EQ(test, err, 0); 749 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size); 750 751 if (params->no_gpu_wait) 752 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, snd_mem); 753 else 754 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, fst_mem); 755 756 ttm_bo_put(bo); 757 ttm_mock_manager_fini(priv->ttm_dev, fst_mem); 758 ttm_mock_manager_fini(priv->ttm_dev, snd_mem); 759 } 760 761 static void ttm_bo_validate_happy_evict(struct kunit *test) 762 { 763 u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT, 764 mem_type_evict = TTM_PL_SYSTEM; 765 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 766 enum ttm_bo_type bo_type = ttm_bo_type_device; 767 u32 small = SZ_8K, medium = SZ_512K, 768 big = MANAGER_SIZE - (small + medium); 769 u32 bo_sizes[] = { small, medium, big }; 770 struct ttm_test_devices *priv = test->priv; 771 struct ttm_buffer_object *bos, *bo_val; 772 struct ttm_placement *placement; 773 struct ttm_place *place; 774 u32 bo_no = 3; 775 int i, err; 776 777 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 778 ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 779 780 place = ttm_place_kunit_init(test, mem_type, 0); 781 placement = ttm_placement_kunit_init(test, place, 1); 782 783 bos = kunit_kmalloc_array(test, bo_no, sizeof(*bos), GFP_KERNEL); 784 KUNIT_ASSERT_NOT_NULL(test, bos); 785 786 memset(bos, 0, sizeof(*bos) * bo_no); 787 for (i = 0; i < bo_no; i++) { 788 drm_gem_private_object_init(priv->drm, &bos[i].base, bo_sizes[i]); 789 err = ttm_bo_init_reserved(priv->ttm_dev, &bos[i], bo_type, placement, 790 PAGE_SIZE, &ctx_init, NULL, NULL, 791 &dummy_ttm_bo_destroy); 792 dma_resv_unlock(bos[i].base.resv); 793 } 794 795 bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 796 bo_val->type = bo_type; 797 798 ttm_bo_reserve(bo_val, false, false, NULL); 799 err = ttm_bo_validate(bo_val, placement, &ctx_val); 800 ttm_bo_unreserve(bo_val); 801 802 KUNIT_EXPECT_EQ(test, err, 0); 803 KUNIT_EXPECT_EQ(test, bos[0].resource->mem_type, mem_type_evict); 804 KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC); 805 KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_PRIV_POPULATED); 806 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, small * 2 + BO_SIZE); 807 KUNIT_EXPECT_EQ(test, bos[1].resource->mem_type, mem_type); 808 809 for (i = 0; i < bo_no; i++) 810 ttm_bo_put(&bos[i]); 811 ttm_bo_put(bo_val); 812 813 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 814 ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 815 } 816 817 static void ttm_bo_validate_all_pinned_evict(struct kunit *test) 818 { 819 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 820 enum ttm_bo_type bo_type = ttm_bo_type_device; 821 struct ttm_buffer_object *bo_big, *bo_small; 822 struct ttm_test_devices *priv = test->priv; 823 struct ttm_placement *placement; 824 u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT; 825 struct ttm_place *place; 826 int err; 827 828 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 829 ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 830 831 place = ttm_place_kunit_init(test, mem_type, 0); 832 placement = ttm_placement_kunit_init(test, place, 1); 833 834 bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL); 835 KUNIT_ASSERT_NOT_NULL(test, bo_big); 836 837 drm_gem_private_object_init(priv->drm, &bo_big->base, MANAGER_SIZE); 838 err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement, 839 PAGE_SIZE, &ctx_init, NULL, NULL, 840 &dummy_ttm_bo_destroy); 841 KUNIT_EXPECT_EQ(test, err, 0); 842 843 ttm_bo_pin(bo_big); 844 dma_resv_unlock(bo_big->base.resv); 845 846 bo_small = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 847 bo_small->type = bo_type; 848 849 ttm_bo_reserve(bo_small, false, false, NULL); 850 err = ttm_bo_validate(bo_small, placement, &ctx_val); 851 ttm_bo_unreserve(bo_small); 852 853 KUNIT_EXPECT_EQ(test, err, -ENOMEM); 854 855 ttm_bo_put(bo_small); 856 857 ttm_bo_reserve(bo_big, false, false, NULL); 858 ttm_bo_unpin(bo_big); 859 dma_resv_unlock(bo_big->base.resv); 860 ttm_bo_put(bo_big); 861 862 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 863 ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 864 } 865 866 static void ttm_bo_validate_allowed_only_evict(struct kunit *test) 867 { 868 u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT, 869 mem_type_evict = TTM_PL_SYSTEM; 870 struct ttm_buffer_object *bo, *bo_evictable, *bo_pinned; 871 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 872 enum ttm_bo_type bo_type = ttm_bo_type_device; 873 struct ttm_test_devices *priv = test->priv; 874 struct ttm_placement *placement; 875 struct ttm_place *place; 876 u32 size = SZ_512K; 877 int err; 878 879 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 880 ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 881 882 place = ttm_place_kunit_init(test, mem_type, 0); 883 placement = ttm_placement_kunit_init(test, place, 1); 884 885 bo_pinned = kunit_kzalloc(test, sizeof(*bo_pinned), GFP_KERNEL); 886 KUNIT_ASSERT_NOT_NULL(test, bo_pinned); 887 888 drm_gem_private_object_init(priv->drm, &bo_pinned->base, size); 889 err = ttm_bo_init_reserved(priv->ttm_dev, bo_pinned, bo_type, placement, 890 PAGE_SIZE, &ctx_init, NULL, NULL, 891 &dummy_ttm_bo_destroy); 892 KUNIT_EXPECT_EQ(test, err, 0); 893 ttm_bo_pin(bo_pinned); 894 dma_resv_unlock(bo_pinned->base.resv); 895 896 bo_evictable = kunit_kzalloc(test, sizeof(*bo_evictable), GFP_KERNEL); 897 KUNIT_ASSERT_NOT_NULL(test, bo_evictable); 898 899 drm_gem_private_object_init(priv->drm, &bo_evictable->base, size); 900 err = ttm_bo_init_reserved(priv->ttm_dev, bo_evictable, bo_type, placement, 901 PAGE_SIZE, &ctx_init, NULL, NULL, 902 &dummy_ttm_bo_destroy); 903 KUNIT_EXPECT_EQ(test, err, 0); 904 dma_resv_unlock(bo_evictable->base.resv); 905 906 bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 907 bo->type = bo_type; 908 909 ttm_bo_reserve(bo, false, false, NULL); 910 err = ttm_bo_validate(bo, placement, &ctx_val); 911 ttm_bo_unreserve(bo); 912 913 KUNIT_EXPECT_EQ(test, err, 0); 914 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type); 915 KUNIT_EXPECT_EQ(test, bo_pinned->resource->mem_type, mem_type); 916 KUNIT_EXPECT_EQ(test, bo_evictable->resource->mem_type, mem_type_evict); 917 KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size * 2 + BO_SIZE); 918 919 ttm_bo_put(bo); 920 ttm_bo_put(bo_evictable); 921 922 ttm_bo_reserve(bo_pinned, false, false, NULL); 923 ttm_bo_unpin(bo_pinned); 924 dma_resv_unlock(bo_pinned->base.resv); 925 ttm_bo_put(bo_pinned); 926 927 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 928 ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 929 } 930 931 static void ttm_bo_validate_deleted_evict(struct kunit *test) 932 { 933 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 934 u32 small = SZ_8K, big = MANAGER_SIZE - BO_SIZE; 935 enum ttm_bo_type bo_type = ttm_bo_type_device; 936 struct ttm_buffer_object *bo_big, *bo_small; 937 struct ttm_test_devices *priv = test->priv; 938 struct ttm_resource_manager *man; 939 u32 mem_type = TTM_PL_VRAM; 940 struct ttm_placement *placement; 941 struct ttm_place *place; 942 int err; 943 944 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 945 man = ttm_manager_type(priv->ttm_dev, mem_type); 946 947 place = ttm_place_kunit_init(test, mem_type, 0); 948 placement = ttm_placement_kunit_init(test, place, 1); 949 950 bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL); 951 KUNIT_ASSERT_NOT_NULL(test, bo_big); 952 953 drm_gem_private_object_init(priv->drm, &bo_big->base, big); 954 err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement, 955 PAGE_SIZE, &ctx_init, NULL, NULL, 956 &dummy_ttm_bo_destroy); 957 KUNIT_EXPECT_EQ(test, err, 0); 958 KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), big); 959 960 dma_resv_unlock(bo_big->base.resv); 961 bo_big->deleted = true; 962 963 bo_small = ttm_bo_kunit_init(test, test->priv, small, NULL); 964 bo_small->type = bo_type; 965 966 ttm_bo_reserve(bo_small, false, false, NULL); 967 err = ttm_bo_validate(bo_small, placement, &ctx_val); 968 ttm_bo_unreserve(bo_small); 969 970 KUNIT_EXPECT_EQ(test, err, 0); 971 KUNIT_EXPECT_EQ(test, bo_small->resource->mem_type, mem_type); 972 KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), small); 973 KUNIT_EXPECT_NULL(test, bo_big->ttm); 974 KUNIT_EXPECT_NULL(test, bo_big->resource); 975 976 ttm_bo_put(bo_small); 977 ttm_bo_put(bo_big); 978 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 979 } 980 981 static void ttm_bo_validate_busy_domain_evict(struct kunit *test) 982 { 983 u32 mem_type = TTM_PL_VRAM, mem_type_evict = TTM_PL_MOCK1; 984 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 985 enum ttm_bo_type bo_type = ttm_bo_type_device; 986 struct ttm_test_devices *priv = test->priv; 987 struct ttm_buffer_object *bo_init, *bo_val; 988 struct ttm_placement *placement; 989 struct ttm_place *place; 990 int err; 991 992 /* 993 * Drop the default device and setup a new one that points to busy 994 * thus unsuitable eviction domain 995 */ 996 ttm_device_fini(priv->ttm_dev); 997 998 err = ttm_device_kunit_init_bad_evict(test->priv, priv->ttm_dev, false, false); 999 KUNIT_ASSERT_EQ(test, err, 0); 1000 1001 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1002 ttm_busy_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE); 1003 1004 place = ttm_place_kunit_init(test, mem_type, 0); 1005 placement = ttm_placement_kunit_init(test, place, 1); 1006 1007 bo_init = kunit_kzalloc(test, sizeof(*bo_init), GFP_KERNEL); 1008 KUNIT_ASSERT_NOT_NULL(test, bo_init); 1009 1010 drm_gem_private_object_init(priv->drm, &bo_init->base, MANAGER_SIZE); 1011 err = ttm_bo_init_reserved(priv->ttm_dev, bo_init, bo_type, placement, 1012 PAGE_SIZE, &ctx_init, NULL, NULL, 1013 &dummy_ttm_bo_destroy); 1014 KUNIT_EXPECT_EQ(test, err, 0); 1015 dma_resv_unlock(bo_init->base.resv); 1016 1017 bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1018 bo_val->type = bo_type; 1019 1020 ttm_bo_reserve(bo_val, false, false, NULL); 1021 err = ttm_bo_validate(bo_val, placement, &ctx_val); 1022 ttm_bo_unreserve(bo_val); 1023 1024 KUNIT_EXPECT_EQ(test, err, -ENOMEM); 1025 KUNIT_EXPECT_EQ(test, bo_init->resource->mem_type, mem_type); 1026 KUNIT_EXPECT_NULL(test, bo_val->resource); 1027 1028 ttm_bo_put(bo_init); 1029 ttm_bo_put(bo_val); 1030 1031 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1032 ttm_bad_manager_fini(priv->ttm_dev, mem_type_evict); 1033 } 1034 1035 static void ttm_bo_validate_evict_gutting(struct kunit *test) 1036 { 1037 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 1038 enum ttm_bo_type bo_type = ttm_bo_type_device; 1039 struct ttm_test_devices *priv = test->priv; 1040 struct ttm_buffer_object *bo, *bo_evict; 1041 u32 mem_type = TTM_PL_MOCK1; 1042 struct ttm_placement *placement; 1043 struct ttm_place *place; 1044 int err; 1045 1046 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1047 1048 place = ttm_place_kunit_init(test, mem_type, 0); 1049 placement = ttm_placement_kunit_init(test, place, 1); 1050 1051 bo_evict = kunit_kzalloc(test, sizeof(*bo_evict), GFP_KERNEL); 1052 KUNIT_ASSERT_NOT_NULL(test, bo_evict); 1053 1054 drm_gem_private_object_init(priv->drm, &bo_evict->base, MANAGER_SIZE); 1055 err = ttm_bo_init_reserved(priv->ttm_dev, bo_evict, bo_type, placement, 1056 PAGE_SIZE, &ctx_init, NULL, NULL, 1057 &dummy_ttm_bo_destroy); 1058 KUNIT_EXPECT_EQ(test, err, 0); 1059 dma_resv_unlock(bo_evict->base.resv); 1060 1061 bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1062 bo->type = bo_type; 1063 1064 ttm_bo_reserve(bo, false, false, NULL); 1065 err = ttm_bo_validate(bo, placement, &ctx_val); 1066 ttm_bo_unreserve(bo); 1067 1068 KUNIT_EXPECT_EQ(test, err, 0); 1069 KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type); 1070 KUNIT_ASSERT_NULL(test, bo_evict->resource); 1071 KUNIT_ASSERT_TRUE(test, bo_evict->ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC); 1072 1073 ttm_bo_put(bo_evict); 1074 ttm_bo_put(bo); 1075 1076 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1077 } 1078 1079 static void ttm_bo_validate_recrusive_evict(struct kunit *test) 1080 { 1081 u32 mem_type = TTM_PL_TT, mem_type_evict = TTM_PL_MOCK2; 1082 struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 1083 struct ttm_placement *placement_tt, *placement_mock; 1084 struct ttm_buffer_object *bo_tt, *bo_mock, *bo_val; 1085 enum ttm_bo_type bo_type = ttm_bo_type_device; 1086 struct ttm_test_devices *priv = test->priv; 1087 struct ttm_place *place_tt, *place_mock; 1088 int err; 1089 1090 ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1091 ttm_mock_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE); 1092 1093 place_tt = ttm_place_kunit_init(test, mem_type, 0); 1094 place_mock = ttm_place_kunit_init(test, mem_type_evict, 0); 1095 1096 placement_tt = ttm_placement_kunit_init(test, place_tt, 1); 1097 placement_mock = ttm_placement_kunit_init(test, place_mock, 1); 1098 1099 bo_tt = kunit_kzalloc(test, sizeof(*bo_tt), GFP_KERNEL); 1100 KUNIT_ASSERT_NOT_NULL(test, bo_tt); 1101 1102 bo_mock = kunit_kzalloc(test, sizeof(*bo_mock), GFP_KERNEL); 1103 KUNIT_ASSERT_NOT_NULL(test, bo_mock); 1104 1105 drm_gem_private_object_init(priv->drm, &bo_tt->base, MANAGER_SIZE); 1106 err = ttm_bo_init_reserved(priv->ttm_dev, bo_tt, bo_type, placement_tt, 1107 PAGE_SIZE, &ctx_init, NULL, NULL, 1108 &dummy_ttm_bo_destroy); 1109 KUNIT_EXPECT_EQ(test, err, 0); 1110 dma_resv_unlock(bo_tt->base.resv); 1111 1112 drm_gem_private_object_init(priv->drm, &bo_mock->base, MANAGER_SIZE); 1113 err = ttm_bo_init_reserved(priv->ttm_dev, bo_mock, bo_type, placement_mock, 1114 PAGE_SIZE, &ctx_init, NULL, NULL, 1115 &dummy_ttm_bo_destroy); 1116 KUNIT_EXPECT_EQ(test, err, 0); 1117 dma_resv_unlock(bo_mock->base.resv); 1118 1119 bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1120 bo_val->type = bo_type; 1121 1122 ttm_bo_reserve(bo_val, false, false, NULL); 1123 err = ttm_bo_validate(bo_val, placement_tt, &ctx_val); 1124 ttm_bo_unreserve(bo_val); 1125 1126 KUNIT_EXPECT_EQ(test, err, 0); 1127 1128 ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1129 ttm_mock_manager_fini(priv->ttm_dev, mem_type_evict); 1130 1131 ttm_bo_put(bo_val); 1132 ttm_bo_put(bo_tt); 1133 ttm_bo_put(bo_mock); 1134 } 1135 1136 static struct kunit_case ttm_bo_validate_test_cases[] = { 1137 KUNIT_CASE_PARAM(ttm_bo_init_reserved_sys_man, ttm_bo_types_gen_params), 1138 KUNIT_CASE_PARAM(ttm_bo_init_reserved_mock_man, ttm_bo_types_gen_params), 1139 KUNIT_CASE(ttm_bo_init_reserved_resv), 1140 KUNIT_CASE_PARAM(ttm_bo_validate_basic, ttm_bo_types_gen_params), 1141 KUNIT_CASE(ttm_bo_validate_invalid_placement), 1142 KUNIT_CASE_PARAM(ttm_bo_validate_same_placement, 1143 ttm_bo_validate_mem_gen_params), 1144 KUNIT_CASE(ttm_bo_validate_failed_alloc), 1145 KUNIT_CASE(ttm_bo_validate_pinned), 1146 KUNIT_CASE(ttm_bo_validate_busy_placement), 1147 KUNIT_CASE_PARAM(ttm_bo_validate_multihop, ttm_bo_types_gen_params), 1148 KUNIT_CASE_PARAM(ttm_bo_validate_no_placement_signaled, 1149 ttm_bo_no_placement_gen_params), 1150 KUNIT_CASE_PARAM(ttm_bo_validate_no_placement_not_signaled, 1151 ttm_bo_types_gen_params), 1152 KUNIT_CASE(ttm_bo_validate_move_fence_signaled), 1153 KUNIT_CASE_PARAM(ttm_bo_validate_move_fence_not_signaled, 1154 ttm_bo_validate_wait_gen_params), 1155 KUNIT_CASE(ttm_bo_validate_happy_evict), 1156 KUNIT_CASE(ttm_bo_validate_all_pinned_evict), 1157 KUNIT_CASE(ttm_bo_validate_allowed_only_evict), 1158 KUNIT_CASE(ttm_bo_validate_deleted_evict), 1159 KUNIT_CASE(ttm_bo_validate_busy_domain_evict), 1160 KUNIT_CASE(ttm_bo_validate_evict_gutting), 1161 KUNIT_CASE(ttm_bo_validate_recrusive_evict), 1162 {} 1163 }; 1164 1165 static struct kunit_suite ttm_bo_validate_test_suite = { 1166 .name = "ttm_bo_validate", 1167 .init = ttm_test_devices_all_init, 1168 .exit = ttm_test_devices_fini, 1169 .test_cases = ttm_bo_validate_test_cases, 1170 }; 1171 1172 kunit_test_suites(&ttm_bo_validate_test_suite); 1173 1174 MODULE_DESCRIPTION("KUnit tests for ttm_bo APIs"); 1175 MODULE_LICENSE("GPL and additional rights"); 1176