File Index
Files and directories
Sign in
FILE

ttm_bo_validate_test.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c C
   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
  18static struct spinlock fence_lock;
  19
  20struct 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
  28static 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
  43static const char *fence_name(struct dma_fence *f)
  44{
  45	return "ttm-bo-validate-fence";
  46}
  47
  48static const struct dma_fence_ops fence_ops = {
  49	.get_driver_name = fence_name,
  50	.get_timeline_name = fence_name,
  51};
  52
  53static 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
  65static 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
  80static 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
  86static 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
 101KUNIT_ARRAY_PARAM(ttm_bo_types, ttm_bo_type_cases,
 102		  ttm_bo_validate_case_desc);
 103
 104static 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_fini(bo);
 148}
 149
 150static 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_fini(bo);
 190	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
 191}
 192
 193static 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_fini(bo);
 225}
 226
 227static 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_fini(bo);
 269	ttm_mock_manager_fini(priv->ttm_dev, snd_mem);
 270}
 271
 272static 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_fini(bo);
 296}
 297
 298static 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_fini(bo);
 325	ttm_bad_manager_fini(priv->ttm_dev, mem_type);
 326}
 327
 328static 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_fini(bo);
 357}
 358
 359static 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
 370KUNIT_ARRAY_PARAM(ttm_bo_validate_mem, ttm_mem_type_cases,
 371		  ttm_bo_validate_case_desc);
 372
 373static 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_fini(bo);
 407
 408	if (params->mem_type != TTM_PL_SYSTEM)
 409		ttm_mock_manager_fini(priv->ttm_dev, params->mem_type);
 410}
 411
 412static 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_fini(bo);
 456	ttm_bad_manager_fini(priv->ttm_dev, fst_mem);
 457	ttm_mock_manager_fini(priv->ttm_dev, snd_mem);
 458}
 459
 460static 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_fini(bo);
 499
 500	ttm_mock_manager_fini(priv->ttm_dev, fst_mem);
 501	ttm_mock_manager_fini(priv->ttm_dev, tmp_mem);
 502}
 503
 504static 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
 514KUNIT_ARRAY_PARAM(ttm_bo_no_placement, ttm_bo_no_placement_cases,
 515		  ttm_bo_validate_case_desc);
 516
 517static 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_fini(bo);
 571}
 572
 573static 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
 589static 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_fini(bo);
 639}
 640
 641static 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->eviction_fences[0] = 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_fini(bo);
 672	dma_fence_put(man->eviction_fences[0]);
 673}
 674
 675static 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
 686KUNIT_ARRAY_PARAM(ttm_bo_validate_wait, ttm_bo_validate_wait_cases,
 687		  ttm_bo_validate_case_desc);
 688
 689static 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
 698static 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->eviction_fences[0] = alloc_mock_fence(test);
 737
 738	task = kthread_create(threaded_fence_signal, man->eviction_fences[0], "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->eviction_fences[0], false, MAX_SCHEDULE_TIMEOUT);
 747	man->eviction_fences[0] = NULL;
 748
 749	KUNIT_EXPECT_EQ(test, err, 0);
 750	KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size);
 751
 752	if (params->no_gpu_wait)
 753		KUNIT_EXPECT_EQ(test, bo->resource->mem_type, snd_mem);
 754	else
 755		KUNIT_EXPECT_EQ(test, bo->resource->mem_type, fst_mem);
 756
 757	ttm_bo_fini(bo);
 758	ttm_mock_manager_fini(priv->ttm_dev, fst_mem);
 759	ttm_mock_manager_fini(priv->ttm_dev, snd_mem);
 760}
 761
 762static void ttm_bo_validate_happy_evict(struct kunit *test)
 763{
 764	u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT,
 765	    mem_type_evict = TTM_PL_SYSTEM;
 766	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
 767	enum ttm_bo_type bo_type = ttm_bo_type_device;
 768	u32 small = SZ_8K, medium = SZ_512K,
 769	    big = MANAGER_SIZE - (small + medium);
 770	u32 bo_sizes[] = { small, medium, big };
 771	struct ttm_test_devices *priv = test->priv;
 772	struct ttm_buffer_object *bos, *bo_val;
 773	struct ttm_placement *placement;
 774	struct ttm_place *place;
 775	u32 bo_no = 3;
 776	int i, err;
 777
 778	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
 779	ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE);
 780
 781	place = ttm_place_kunit_init(test, mem_type, 0);
 782	placement = ttm_placement_kunit_init(test, place, 1);
 783
 784	bos = kunit_kmalloc_array(test, bo_no, sizeof(*bos), GFP_KERNEL);
 785	KUNIT_ASSERT_NOT_NULL(test, bos);
 786
 787	memset(bos, 0, sizeof(*bos) * bo_no);
 788	for (i = 0; i < bo_no; i++) {
 789		drm_gem_private_object_init(priv->drm, &bos[i].base, bo_sizes[i]);
 790		err = ttm_bo_init_reserved(priv->ttm_dev, &bos[i], bo_type, placement,
 791					   PAGE_SIZE, &ctx_init, NULL, NULL,
 792					   &dummy_ttm_bo_destroy);
 793		dma_resv_unlock(bos[i].base.resv);
 794	}
 795
 796	bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
 797	bo_val->type = bo_type;
 798
 799	ttm_bo_reserve(bo_val, false, false, NULL);
 800	err = ttm_bo_validate(bo_val, placement, &ctx_val);
 801	ttm_bo_unreserve(bo_val);
 802
 803	KUNIT_EXPECT_EQ(test, err, 0);
 804	KUNIT_EXPECT_EQ(test, bos[0].resource->mem_type, mem_type_evict);
 805	KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC);
 806	KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_PRIV_POPULATED);
 807	KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, small * 2 + BO_SIZE);
 808	KUNIT_EXPECT_EQ(test, bos[1].resource->mem_type, mem_type);
 809
 810	for (i = 0; i < bo_no; i++)
 811		ttm_bo_fini(&bos[i]);
 812	ttm_bo_fini(bo_val);
 813
 814	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
 815	ttm_mock_manager_fini(priv->ttm_dev, mem_multihop);
 816}
 817
 818static void ttm_bo_validate_all_pinned_evict(struct kunit *test)
 819{
 820	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
 821	enum ttm_bo_type bo_type = ttm_bo_type_device;
 822	struct ttm_buffer_object *bo_big, *bo_small;
 823	struct ttm_test_devices *priv = test->priv;
 824	struct ttm_placement *placement;
 825	u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT;
 826	struct ttm_place *place;
 827	int err;
 828
 829	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
 830	ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE);
 831
 832	place = ttm_place_kunit_init(test, mem_type, 0);
 833	placement = ttm_placement_kunit_init(test, place, 1);
 834
 835	bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL);
 836	KUNIT_ASSERT_NOT_NULL(test, bo_big);
 837
 838	drm_gem_private_object_init(priv->drm, &bo_big->base, MANAGER_SIZE);
 839	err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement,
 840				   PAGE_SIZE, &ctx_init, NULL, NULL,
 841				   &dummy_ttm_bo_destroy);
 842	KUNIT_EXPECT_EQ(test, err, 0);
 843
 844	ttm_bo_pin(bo_big);
 845	dma_resv_unlock(bo_big->base.resv);
 846
 847	bo_small = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
 848	bo_small->type = bo_type;
 849
 850	ttm_bo_reserve(bo_small, false, false, NULL);
 851	err = ttm_bo_validate(bo_small, placement, &ctx_val);
 852	ttm_bo_unreserve(bo_small);
 853
 854	KUNIT_EXPECT_EQ(test, err, -ENOMEM);
 855
 856	ttm_bo_fini(bo_small);
 857
 858	ttm_bo_reserve(bo_big, false, false, NULL);
 859	ttm_bo_unpin(bo_big);
 860	dma_resv_unlock(bo_big->base.resv);
 861	ttm_bo_fini(bo_big);
 862
 863	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
 864	ttm_mock_manager_fini(priv->ttm_dev, mem_multihop);
 865}
 866
 867static void ttm_bo_validate_allowed_only_evict(struct kunit *test)
 868{
 869	u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT,
 870	    mem_type_evict = TTM_PL_SYSTEM;
 871	struct ttm_buffer_object *bo, *bo_evictable, *bo_pinned;
 872	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
 873	enum ttm_bo_type bo_type = ttm_bo_type_device;
 874	struct ttm_test_devices *priv = test->priv;
 875	struct ttm_placement *placement;
 876	struct ttm_place *place;
 877	u32 size = SZ_512K;
 878	int err;
 879
 880	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
 881	ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE);
 882
 883	place = ttm_place_kunit_init(test, mem_type, 0);
 884	placement = ttm_placement_kunit_init(test, place, 1);
 885
 886	bo_pinned = kunit_kzalloc(test, sizeof(*bo_pinned), GFP_KERNEL);
 887	KUNIT_ASSERT_NOT_NULL(test, bo_pinned);
 888
 889	drm_gem_private_object_init(priv->drm, &bo_pinned->base, size);
 890	err = ttm_bo_init_reserved(priv->ttm_dev, bo_pinned, bo_type, placement,
 891				   PAGE_SIZE, &ctx_init, NULL, NULL,
 892				   &dummy_ttm_bo_destroy);
 893	KUNIT_EXPECT_EQ(test, err, 0);
 894	ttm_bo_pin(bo_pinned);
 895	dma_resv_unlock(bo_pinned->base.resv);
 896
 897	bo_evictable = kunit_kzalloc(test, sizeof(*bo_evictable), GFP_KERNEL);
 898	KUNIT_ASSERT_NOT_NULL(test, bo_evictable);
 899
 900	drm_gem_private_object_init(priv->drm, &bo_evictable->base, size);
 901	err = ttm_bo_init_reserved(priv->ttm_dev, bo_evictable, bo_type, placement,
 902				   PAGE_SIZE, &ctx_init, NULL, NULL,
 903				   &dummy_ttm_bo_destroy);
 904	KUNIT_EXPECT_EQ(test, err, 0);
 905	dma_resv_unlock(bo_evictable->base.resv);
 906
 907	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
 908	bo->type = bo_type;
 909
 910	ttm_bo_reserve(bo, false, false, NULL);
 911	err = ttm_bo_validate(bo, placement, &ctx_val);
 912	ttm_bo_unreserve(bo);
 913
 914	KUNIT_EXPECT_EQ(test, err, 0);
 915	KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type);
 916	KUNIT_EXPECT_EQ(test, bo_pinned->resource->mem_type, mem_type);
 917	KUNIT_EXPECT_EQ(test, bo_evictable->resource->mem_type, mem_type_evict);
 918	KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size * 2 + BO_SIZE);
 919
 920	ttm_bo_fini(bo);
 921	ttm_bo_fini(bo_evictable);
 922
 923	ttm_bo_reserve(bo_pinned, false, false, NULL);
 924	ttm_bo_unpin(bo_pinned);
 925	dma_resv_unlock(bo_pinned->base.resv);
 926	ttm_bo_fini(bo_pinned);
 927
 928	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
 929	ttm_mock_manager_fini(priv->ttm_dev, mem_multihop);
 930}
 931
 932static void ttm_bo_validate_deleted_evict(struct kunit *test)
 933{
 934	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
 935	u32 small = SZ_8K, big = MANAGER_SIZE - BO_SIZE;
 936	enum ttm_bo_type bo_type = ttm_bo_type_device;
 937	struct ttm_buffer_object *bo_big, *bo_small;
 938	struct ttm_test_devices *priv = test->priv;
 939	struct ttm_resource_manager *man;
 940	u32 mem_type = TTM_PL_VRAM;
 941	struct ttm_placement *placement;
 942	struct ttm_place *place;
 943	int err;
 944
 945	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
 946	man = ttm_manager_type(priv->ttm_dev, mem_type);
 947
 948	place = ttm_place_kunit_init(test, mem_type, 0);
 949	placement = ttm_placement_kunit_init(test, place, 1);
 950
 951	bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL);
 952	KUNIT_ASSERT_NOT_NULL(test, bo_big);
 953
 954	drm_gem_private_object_init(priv->drm, &bo_big->base, big);
 955	err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement,
 956				   PAGE_SIZE, &ctx_init, NULL, NULL,
 957				   &dummy_ttm_bo_destroy);
 958	KUNIT_EXPECT_EQ(test, err, 0);
 959	KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), big);
 960
 961	dma_resv_unlock(bo_big->base.resv);
 962	bo_big->deleted = true;
 963
 964	bo_small = ttm_bo_kunit_init(test, test->priv, small, NULL);
 965	bo_small->type = bo_type;
 966
 967	ttm_bo_reserve(bo_small, false, false, NULL);
 968	err = ttm_bo_validate(bo_small, placement, &ctx_val);
 969	ttm_bo_unreserve(bo_small);
 970
 971	KUNIT_EXPECT_EQ(test, err, 0);
 972	KUNIT_EXPECT_EQ(test, bo_small->resource->mem_type, mem_type);
 973	KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), small);
 974	KUNIT_EXPECT_NULL(test, bo_big->ttm);
 975	KUNIT_EXPECT_NULL(test, bo_big->resource);
 976
 977	ttm_bo_fini(bo_small);
 978	ttm_bo_fini(bo_big);
 979	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
 980}
 981
 982static void ttm_bo_validate_busy_domain_evict(struct kunit *test)
 983{
 984	u32 mem_type = TTM_PL_VRAM, mem_type_evict = TTM_PL_MOCK1;
 985	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
 986	enum ttm_bo_type bo_type = ttm_bo_type_device;
 987	struct ttm_test_devices *priv = test->priv;
 988	struct ttm_buffer_object *bo_init, *bo_val;
 989	struct ttm_placement *placement;
 990	struct ttm_place *place;
 991	int err;
 992
 993	/*
 994	 * Drop the default device and setup a new one that points to busy
 995	 * thus unsuitable eviction domain
 996	 */
 997	ttm_device_fini(priv->ttm_dev);
 998
 999	err = ttm_device_kunit_init_bad_evict(test->priv, priv->ttm_dev);
1000	KUNIT_ASSERT_EQ(test, err, 0);
1001
1002	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
1003	ttm_busy_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE);
1004
1005	place = ttm_place_kunit_init(test, mem_type, 0);
1006	placement = ttm_placement_kunit_init(test, place, 1);
1007
1008	bo_init = kunit_kzalloc(test, sizeof(*bo_init), GFP_KERNEL);
1009	KUNIT_ASSERT_NOT_NULL(test, bo_init);
1010
1011	drm_gem_private_object_init(priv->drm, &bo_init->base, MANAGER_SIZE);
1012	err = ttm_bo_init_reserved(priv->ttm_dev, bo_init, bo_type, placement,
1013				   PAGE_SIZE, &ctx_init, NULL, NULL,
1014				   &dummy_ttm_bo_destroy);
1015	KUNIT_EXPECT_EQ(test, err, 0);
1016	dma_resv_unlock(bo_init->base.resv);
1017
1018	bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
1019	bo_val->type = bo_type;
1020
1021	ttm_bo_reserve(bo_val, false, false, NULL);
1022	err = ttm_bo_validate(bo_val, placement, &ctx_val);
1023	ttm_bo_unreserve(bo_val);
1024
1025	KUNIT_EXPECT_EQ(test, err, -ENOMEM);
1026	KUNIT_EXPECT_EQ(test, bo_init->resource->mem_type, mem_type);
1027	KUNIT_EXPECT_NULL(test, bo_val->resource);
1028
1029	ttm_bo_fini(bo_init);
1030	ttm_bo_fini(bo_val);
1031
1032	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
1033	ttm_bad_manager_fini(priv->ttm_dev, mem_type_evict);
1034}
1035
1036static void ttm_bo_validate_evict_gutting(struct kunit *test)
1037{
1038	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
1039	enum ttm_bo_type bo_type = ttm_bo_type_device;
1040	struct ttm_test_devices *priv = test->priv;
1041	struct ttm_buffer_object *bo, *bo_evict;
1042	u32 mem_type = TTM_PL_MOCK1;
1043	struct ttm_placement *placement;
1044	struct ttm_place *place;
1045	int err;
1046
1047	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
1048
1049	place = ttm_place_kunit_init(test, mem_type, 0);
1050	placement = ttm_placement_kunit_init(test, place, 1);
1051
1052	bo_evict = kunit_kzalloc(test, sizeof(*bo_evict), GFP_KERNEL);
1053	KUNIT_ASSERT_NOT_NULL(test, bo_evict);
1054
1055	drm_gem_private_object_init(priv->drm, &bo_evict->base, MANAGER_SIZE);
1056	err = ttm_bo_init_reserved(priv->ttm_dev, bo_evict, bo_type, placement,
1057				   PAGE_SIZE, &ctx_init, NULL, NULL,
1058				   &dummy_ttm_bo_destroy);
1059	KUNIT_EXPECT_EQ(test, err, 0);
1060	dma_resv_unlock(bo_evict->base.resv);
1061
1062	bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
1063	bo->type = bo_type;
1064
1065	ttm_bo_reserve(bo, false, false, NULL);
1066	err = ttm_bo_validate(bo, placement, &ctx_val);
1067	ttm_bo_unreserve(bo);
1068
1069	KUNIT_EXPECT_EQ(test, err, 0);
1070	KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type);
1071	KUNIT_ASSERT_NULL(test, bo_evict->resource);
1072	KUNIT_ASSERT_TRUE(test, bo_evict->ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC);
1073
1074	ttm_bo_fini(bo_evict);
1075	ttm_bo_fini(bo);
1076
1077	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
1078}
1079
1080static void ttm_bo_validate_recrusive_evict(struct kunit *test)
1081{
1082	u32 mem_type = TTM_PL_TT, mem_type_evict = TTM_PL_MOCK2;
1083	struct ttm_operation_ctx ctx_init = { }, ctx_val  = { };
1084	struct ttm_placement *placement_tt, *placement_mock;
1085	struct ttm_buffer_object *bo_tt, *bo_mock, *bo_val;
1086	enum ttm_bo_type bo_type = ttm_bo_type_device;
1087	struct ttm_test_devices *priv = test->priv;
1088	struct ttm_place *place_tt, *place_mock;
1089	int err;
1090
1091	ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE);
1092	ttm_mock_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE);
1093
1094	place_tt = ttm_place_kunit_init(test, mem_type, 0);
1095	place_mock = ttm_place_kunit_init(test, mem_type_evict, 0);
1096
1097	placement_tt = ttm_placement_kunit_init(test, place_tt, 1);
1098	placement_mock = ttm_placement_kunit_init(test, place_mock, 1);
1099
1100	bo_tt = kunit_kzalloc(test, sizeof(*bo_tt), GFP_KERNEL);
1101	KUNIT_ASSERT_NOT_NULL(test, bo_tt);
1102
1103	bo_mock = kunit_kzalloc(test, sizeof(*bo_mock), GFP_KERNEL);
1104	KUNIT_ASSERT_NOT_NULL(test, bo_mock);
1105
1106	drm_gem_private_object_init(priv->drm, &bo_tt->base, MANAGER_SIZE);
1107	err = ttm_bo_init_reserved(priv->ttm_dev, bo_tt, bo_type, placement_tt,
1108				   PAGE_SIZE, &ctx_init, NULL, NULL,
1109				   &dummy_ttm_bo_destroy);
1110	KUNIT_EXPECT_EQ(test, err, 0);
1111	dma_resv_unlock(bo_tt->base.resv);
1112
1113	drm_gem_private_object_init(priv->drm, &bo_mock->base, MANAGER_SIZE);
1114	err = ttm_bo_init_reserved(priv->ttm_dev, bo_mock, bo_type, placement_mock,
1115				   PAGE_SIZE, &ctx_init, NULL, NULL,
1116				   &dummy_ttm_bo_destroy);
1117	KUNIT_EXPECT_EQ(test, err, 0);
1118	dma_resv_unlock(bo_mock->base.resv);
1119
1120	bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL);
1121	bo_val->type = bo_type;
1122
1123	ttm_bo_reserve(bo_val, false, false, NULL);
1124	err = ttm_bo_validate(bo_val, placement_tt, &ctx_val);
1125	ttm_bo_unreserve(bo_val);
1126
1127	KUNIT_EXPECT_EQ(test, err, 0);
1128
1129	ttm_mock_manager_fini(priv->ttm_dev, mem_type);
1130	ttm_mock_manager_fini(priv->ttm_dev, mem_type_evict);
1131
1132	ttm_bo_fini(bo_val);
1133	ttm_bo_fini(bo_tt);
1134	ttm_bo_fini(bo_mock);
1135}
1136
1137static struct kunit_case ttm_bo_validate_test_cases[] = {
1138	KUNIT_CASE_PARAM(ttm_bo_init_reserved_sys_man, ttm_bo_types_gen_params),
1139	KUNIT_CASE_PARAM(ttm_bo_init_reserved_mock_man, ttm_bo_types_gen_params),
1140	KUNIT_CASE(ttm_bo_init_reserved_resv),
1141	KUNIT_CASE_PARAM(ttm_bo_validate_basic, ttm_bo_types_gen_params),
1142	KUNIT_CASE(ttm_bo_validate_invalid_placement),
1143	KUNIT_CASE_PARAM(ttm_bo_validate_same_placement,
1144			 ttm_bo_validate_mem_gen_params),
1145	KUNIT_CASE(ttm_bo_validate_failed_alloc),
1146	KUNIT_CASE(ttm_bo_validate_pinned),
1147	KUNIT_CASE(ttm_bo_validate_busy_placement),
1148	KUNIT_CASE_PARAM(ttm_bo_validate_multihop, ttm_bo_types_gen_params),
1149	KUNIT_CASE_PARAM(ttm_bo_validate_no_placement_signaled,
1150			 ttm_bo_no_placement_gen_params),
1151	KUNIT_CASE_PARAM(ttm_bo_validate_no_placement_not_signaled,
1152			 ttm_bo_types_gen_params),
1153	KUNIT_CASE(ttm_bo_validate_move_fence_signaled),
1154	KUNIT_CASE_PARAM(ttm_bo_validate_move_fence_not_signaled,
1155			 ttm_bo_validate_wait_gen_params),
1156	KUNIT_CASE(ttm_bo_validate_happy_evict),
1157	KUNIT_CASE(ttm_bo_validate_all_pinned_evict),
1158	KUNIT_CASE(ttm_bo_validate_allowed_only_evict),
1159	KUNIT_CASE(ttm_bo_validate_deleted_evict),
1160	KUNIT_CASE(ttm_bo_validate_busy_domain_evict),
1161	KUNIT_CASE(ttm_bo_validate_evict_gutting),
1162	KUNIT_CASE(ttm_bo_validate_recrusive_evict),
1163	{}
1164};
1165
1166static struct kunit_suite ttm_bo_validate_test_suite = {
1167	.name = "ttm_bo_validate",
1168	.init = ttm_test_devices_all_init,
1169	.exit = ttm_test_devices_fini,
1170	.test_cases = ttm_bo_validate_test_cases,
1171};
1172
1173kunit_test_suites(&ttm_bo_validate_test_suite);
1174
1175MODULE_DESCRIPTION("KUnit tests for ttm_bo APIs");
1176MODULE_LICENSE("GPL and additional rights");
~/ Read-only file preview.