[PATCH v2 2/4] drm/xe/kunit: Extend GuC ID manager split-pool coverage
Piórkowski, Piotr <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
From: Piotr Piórkowski <[email protected]> Expand the GuC ID manager KUnit coverage to exercise the new usable/shareable pool model. v2: Use KUNIT_EXPECT instead of KUNIT_ASSERT inside the locked section so the mutex is not leaked on failure (Sashiko). Signed-off-by: Piotr Piórkowski <[email protected]> Cc: Michal Wajdeczko <[email protected]> --- drivers/gpu/drm/xe/tests/xe_guc_id_mgr_test.c | 383 ++++++++++++++++++ 1 file changed, 383 insertions(+) diff --git a/drivers/gpu/drm/xe/tests/xe_guc_id_mgr_test.c b/drivers/gpu/drm/xe/tests/xe_guc_id_mgr_test.c index 103ea82d278e..295c17dbc21f 100644 --- a/drivers/gpu/drm/xe/tests/xe_guc_id_mgr_test.c +++ b/drivers/gpu/drm/xe/tests/xe_guc_id_mgr_test.c @@ -119,12 +119,395 @@ static void check_all(struct kunit *test) mutex_unlock(idm_mutex(idm)); } +static void check_limits(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 10, 20)); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_usable(idm), 10); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_shareable(idm), 20); + KUNIT_EXPECT_EQ(test, idm_total(idm), 30); +} + +static void check_overlap(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, GUC_ID_MAX, GUC_ID_MAX)); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_usable(idm), GUC_ID_MAX); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_shareable(idm), GUC_ID_MAX); + KUNIT_EXPECT_EQ(test, idm_total(idm), GUC_ID_MAX); +} + +static void check_overlap_alloc(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int total; + int usable_id, shareable_id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, GUC_ID_MAX, GUC_ID_MAX)); + + mutex_lock(idm_mutex(idm)); + total = idm_total(idm); + + usable_id = xe_guc_id_mgr_reserve_usable_locked(idm, 2); + KUNIT_EXPECT_EQ(test, usable_id, 0); + + shareable_id = xe_guc_id_mgr_reserve_shareable_locked(idm, 3, 0); + KUNIT_EXPECT_EQ(test, shareable_id, total - 3); + + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 5); + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 5); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 5); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, usable_id, 2), 0); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, shareable_id, 3), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_overlap_release(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int total; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, GUC_ID_MAX, GUC_ID_MAX)); + + mutex_lock(idm_mutex(idm)); + total = idm_total(idm); + + id = xe_guc_id_mgr_reserve_usable_locked(idm, 4); + KUNIT_EXPECT_EQ(test, id, 0); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, id, 4), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + id = xe_guc_id_mgr_reserve_shareable_locked(idm, 4, 0); + KUNIT_EXPECT_EQ(test, id, total - 4); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, id, 4), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, 0, 0), -EINVAL); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, 0, 0), -EINVAL); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_overlap_partial_init(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int pools_size = (GUC_ID_MAX / 3) * 2; + unsigned int shareable_start; + unsigned int rest; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, pools_size, pools_size)); + + mutex_lock(idm_mutex(idm)); + + shareable_start = idm_shareable_start(idm); + rest = idm_total(idm) - pools_size; + + KUNIT_EXPECT_EQ(test, idm_total(idm), GUC_ID_MAX); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_usable(idm), pools_size); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_max_shareable(idm), pools_size); + KUNIT_EXPECT_EQ(test, shareable_start, GUC_ID_MAX - pools_size); + + id = xe_guc_id_mgr_reserve_usable_locked(idm, pools_size); + KUNIT_EXPECT_EQ(test, id, 0); + + id = xe_guc_id_mgr_reserve_shareable_locked(idm, rest, 0); + KUNIT_EXPECT_EQ(test, id, pools_size); + + KUNIT_EXPECT_EQ(test, idm_used_total(idm), GUC_ID_MAX); + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), pools_size); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), pools_size); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, 0, pools_size), 0); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, pools_size, rest), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_overlap_partial_shared_range_blocking(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int pools_size = (GUC_ID_MAX / 3) * 2; + int usable_id, shareable_range_id, shareable_overlap_id; + unsigned int shareable_start; + unsigned int nonoverlap_size; + unsigned int overlap_size; + unsigned int total; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, pools_size, pools_size)); + + mutex_lock(idm_mutex(idm)); + + total = idm_total(idm); + shareable_start = idm_shareable_start(idm); + nonoverlap_size = total - pools_size; + overlap_size = pools_size - shareable_start; + + KUNIT_EXPECT_GT(test, nonoverlap_size, 0); + KUNIT_EXPECT_GT(test, overlap_size, 0); + + shareable_range_id = xe_guc_id_mgr_reserve_shareable_locked(idm, nonoverlap_size, 0); + KUNIT_EXPECT_EQ(test, shareable_range_id, pools_size); + + usable_id = xe_guc_id_mgr_reserve_usable_locked(idm, pools_size); + KUNIT_EXPECT_EQ(test, usable_id, 0); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_reserve_shareable_locked(idm, 1, 0), -ENOSPC); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, usable_id, pools_size), 0); + + shareable_overlap_id = xe_guc_id_mgr_reserve_shareable_locked(idm, overlap_size, 0); + KUNIT_EXPECT_EQ(test, shareable_overlap_id, shareable_start); + + usable_id = xe_guc_id_mgr_reserve_usable_locked(idm, shareable_start); + KUNIT_EXPECT_EQ(test, usable_id, 0); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_reserve_usable_locked(idm, 1), -ENOSPC); + + KUNIT_EXPECT_EQ(test, + xe_guc_id_mgr_release_usable_locked(idm, usable_id, shareable_start), + 0); + KUNIT_EXPECT_EQ(test, + xe_guc_id_mgr_release_shareable_locked(idm, shareable_overlap_id, + overlap_size), + 0); + KUNIT_EXPECT_EQ(test, + xe_guc_id_mgr_release_shareable_locked(idm, shareable_range_id, + nonoverlap_size), + 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_used_usable(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 8, 8)); + + mutex_lock(idm_mutex(idm)); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 0); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 0); + + id = xe_guc_id_mgr_reserve_usable_locked(idm, 2); + KUNIT_EXPECT_GE(test, id, 0); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 2); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 2); + + idm_release_chunk_locked(idm, id, 2); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_used_shareable(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int shareable_start; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 8, 8)); + + mutex_lock(idm_mutex(idm)); + shareable_start = idm_shareable_start(idm); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 0); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 0); + + id = xe_guc_id_mgr_reserve_shareable_locked(idm, 3, 0); + KUNIT_EXPECT_EQ(test, id, shareable_start); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 0); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 3); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 3); + + idm_release_chunk_locked(idm, id, 3); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_used_mixed(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int shareable_start; + int usable_id, shareable_id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 8, 8)); + + mutex_lock(idm_mutex(idm)); + shareable_start = idm_shareable_start(idm); + + usable_id = xe_guc_id_mgr_reserve_usable_locked(idm, 2); + KUNIT_EXPECT_EQ(test, usable_id, 0); + + shareable_id = xe_guc_id_mgr_reserve_shareable_locked(idm, 3, 0); + KUNIT_EXPECT_EQ(test, shareable_id, shareable_start); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 2); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 3); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 5); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, usable_id, 2), 0); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, shareable_id, 3), 0); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_release_usable_range(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 8, 8)); + + mutex_lock(idm_mutex(idm)); + + id = xe_guc_id_mgr_reserve_usable_locked(idm, 4); + KUNIT_EXPECT_EQ(test, id, 0); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, 4, 7), -ERANGE); + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 4); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, 0, 0), -EINVAL); + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 4); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_usable_locked(idm, id, 4), 0); + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_release_shareable_range(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int shareable_start; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 8, 8)); + + mutex_lock(idm_mutex(idm)); + + shareable_start = idm_shareable_start(idm); + id = xe_guc_id_mgr_reserve_shareable_locked(idm, 4, 0); + KUNIT_EXPECT_EQ(test, id, shareable_start); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, 4, 7), -ERANGE); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 4); + + KUNIT_EXPECT_EQ(test, + xe_guc_id_mgr_release_shareable_locked(idm, shareable_start, 0), + -EINVAL); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 4); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_release_shareable_locked(idm, id, 4), 0); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_split_boundaries(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int shareable_start; + int id; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, 4, 4)); + + mutex_lock(idm_mutex(idm)); + + shareable_start = idm_shareable_start(idm); + + id = xe_guc_id_mgr_reserve_usable_locked(idm, 4); + KUNIT_EXPECT_EQ(test, id, 0); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_reserve_usable_locked(idm, 1), -ENOSPC); + + id = xe_guc_id_mgr_reserve_shareable_locked(idm, 4, 0); + KUNIT_EXPECT_EQ(test, id, shareable_start); + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_reserve_shareable_locked(idm, 1, 0), -ENOSPC); + + KUNIT_EXPECT_EQ(test, idm_used_usable(idm), 4); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 4); + + idm_release_chunk_locked(idm, 0, 4); + idm_release_chunk_locked(idm, shareable_start, 4); + KUNIT_EXPECT_EQ(test, idm_used_total(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + +static void check_shareable_spare(struct kunit *test) +{ + struct xe_guc_id_mgr *idm = test->priv; + unsigned int pools_size = (GUC_ID_MAX / 3) * 2; + unsigned int shareable_start; + unsigned int overlap_size; + unsigned int shared_tail; + int id_tail, id_overlap; + + KUNIT_ASSERT_EQ(test, 0, idm_init(idm, pools_size, pools_size)); + + mutex_lock(idm_mutex(idm)); + shareable_start = idm_shareable_start(idm); + overlap_size = idm->usable - shareable_start; + shared_tail = idm_total(idm) - idm->usable; + + KUNIT_EXPECT_GT(test, overlap_size, 0); + KUNIT_EXPECT_GT(test, shared_tail, 0); + + id_tail = xe_guc_id_mgr_reserve_shareable_locked(idm, shared_tail, 1); + KUNIT_EXPECT_EQ(test, id_tail, idm->usable); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), shared_tail); + + id_overlap = xe_guc_id_mgr_reserve_shareable_locked(idm, overlap_size - 1, 1); + KUNIT_EXPECT_EQ(test, id_overlap, shareable_start + 1); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), idm->shareable - 1); + + KUNIT_EXPECT_EQ(test, xe_guc_id_mgr_reserve_shareable_locked(idm, 1, 1), -EDQUOT); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), idm->shareable - 1); + + idm_release_chunk_locked(idm, id_tail, shared_tail); + idm_release_chunk_locked(idm, id_overlap, overlap_size - 1); + KUNIT_EXPECT_EQ(test, idm_used_shareable(idm), 0); + + mutex_unlock(idm_mutex(idm)); +} + static struct kunit_case guc_id_mgr_test_cases[] = { KUNIT_CASE(bad_init), KUNIT_CASE(no_init), KUNIT_CASE(init_fini), KUNIT_CASE(check_used), KUNIT_CASE(check_quota), + KUNIT_CASE(check_limits), + KUNIT_CASE(check_overlap), + KUNIT_CASE(check_overlap_alloc), + KUNIT_CASE(check_overlap_release), + KUNIT_CASE(check_overlap_partial_init), + KUNIT_CASE(check_overlap_partial_shared_range_blocking), + KUNIT_CASE(check_used_usable), + KUNIT_CASE(check_used_shareable), + KUNIT_CASE(check_used_mixed), + KUNIT_CASE(check_release_usable_range), + KUNIT_CASE(check_release_shareable_range), + KUNIT_CASE(check_split_boundaries), + KUNIT_CASE(check_shareable_spare), KUNIT_CASE_SLOW(check_all), {} }; -- 2.34.1