| 1 | // SPDX-License-Identifier: GPL-2.0 AND MIT |
| 2 | /* |
| 3 | * Copyright © 2024 Intel Corporation |
| 4 | */ |
| 5 | |
| 6 | #include <kunit/test.h> |
| 7 | |
| 8 | #include "xe_device.h" |
| 9 | #include "xe_kunit_helpers.h" |
| 10 | |
| 11 | static int guc_id_mgr_test_init(struct kunit *test) |
| 12 | { |
| 13 | struct xe_guc_id_mgr *idm; |
| 14 | |
| 15 | xe_kunit_helper_xe_device_test_init(test); |
| 16 | idm = &xe_device_get_gt(xe: test->priv, gt_id: 0)->uc.guc.submission_state.idm; |
| 17 | |
| 18 | mutex_init(idm_mutex(idm)); |
| 19 | test->priv = idm; |
| 20 | return 0; |
| 21 | } |
| 22 | |
| 23 | static void bad_init(struct kunit *test) |
| 24 | { |
| 25 | struct xe_guc_id_mgr *idm = test->priv; |
| 26 | |
| 27 | KUNIT_EXPECT_EQ(test, -EINVAL, xe_guc_id_mgr_init(idm, 0)); |
| 28 | KUNIT_EXPECT_EQ(test, -ERANGE, xe_guc_id_mgr_init(idm, GUC_ID_MAX + 1)); |
| 29 | } |
| 30 | |
| 31 | static void no_init(struct kunit *test) |
| 32 | { |
| 33 | struct xe_guc_id_mgr *idm = test->priv; |
| 34 | |
| 35 | mutex_lock(idm_mutex(idm)); |
| 36 | KUNIT_EXPECT_EQ(test, -ENODATA, xe_guc_id_mgr_reserve_locked(idm, 0)); |
| 37 | mutex_unlock(lock: idm_mutex(idm)); |
| 38 | |
| 39 | KUNIT_EXPECT_EQ(test, -ENODATA, xe_guc_id_mgr_reserve(idm, 1, 1)); |
| 40 | } |
| 41 | |
| 42 | static void init_fini(struct kunit *test) |
| 43 | { |
| 44 | struct xe_guc_id_mgr *idm = test->priv; |
| 45 | |
| 46 | KUNIT_ASSERT_EQ(test, 0, xe_guc_id_mgr_init(idm, -1)); |
| 47 | KUNIT_EXPECT_NOT_NULL(test, idm->bitmap); |
| 48 | KUNIT_EXPECT_EQ(test, idm->total, GUC_ID_MAX); |
| 49 | __fini_idm(NULL, idm); |
| 50 | KUNIT_EXPECT_NULL(test, idm->bitmap); |
| 51 | KUNIT_EXPECT_EQ(test, idm->total, 0); |
| 52 | } |
| 53 | |
| 54 | static void check_used(struct kunit *test) |
| 55 | { |
| 56 | struct xe_guc_id_mgr *idm = test->priv; |
| 57 | unsigned int n; |
| 58 | |
| 59 | KUNIT_ASSERT_EQ(test, 0, xe_guc_id_mgr_init(idm, 2)); |
| 60 | |
| 61 | mutex_lock(idm_mutex(idm)); |
| 62 | |
| 63 | for (n = 0; n < idm->total; n++) { |
| 64 | kunit_info(test, "n=%u" , n); |
| 65 | KUNIT_EXPECT_EQ(test, idm->used, n); |
| 66 | KUNIT_EXPECT_GE(test, idm_reserve_chunk_locked(idm, 1, 0), 0); |
| 67 | KUNIT_EXPECT_EQ(test, idm->used, n + 1); |
| 68 | } |
| 69 | KUNIT_EXPECT_EQ(test, idm->used, idm->total); |
| 70 | idm_release_chunk_locked(idm, 0, idm->used); |
| 71 | KUNIT_EXPECT_EQ(test, idm->used, 0); |
| 72 | |
| 73 | mutex_unlock(lock: idm_mutex(idm)); |
| 74 | } |
| 75 | |
| 76 | static void check_quota(struct kunit *test) |
| 77 | { |
| 78 | struct xe_guc_id_mgr *idm = test->priv; |
| 79 | unsigned int n; |
| 80 | |
| 81 | KUNIT_ASSERT_EQ(test, 0, xe_guc_id_mgr_init(idm, 2)); |
| 82 | |
| 83 | mutex_lock(idm_mutex(idm)); |
| 84 | |
| 85 | for (n = 0; n < idm->total - 1; n++) { |
| 86 | kunit_info(test, "n=%u" , n); |
| 87 | KUNIT_EXPECT_EQ(test, idm_reserve_chunk_locked(idm, 1, idm->total), -EDQUOT); |
| 88 | KUNIT_EXPECT_EQ(test, idm_reserve_chunk_locked(idm, 1, idm->total - n), -EDQUOT); |
| 89 | KUNIT_EXPECT_EQ(test, idm_reserve_chunk_locked(idm, idm->total - n, 1), -EDQUOT); |
| 90 | KUNIT_EXPECT_GE(test, idm_reserve_chunk_locked(idm, 1, 1), 0); |
| 91 | } |
| 92 | KUNIT_EXPECT_LE(test, 0, idm_reserve_chunk_locked(idm, 1, 0)); |
| 93 | KUNIT_EXPECT_EQ(test, idm->used, idm->total); |
| 94 | idm_release_chunk_locked(idm, 0, idm->total); |
| 95 | KUNIT_EXPECT_EQ(test, idm->used, 0); |
| 96 | |
| 97 | mutex_unlock(lock: idm_mutex(idm)); |
| 98 | } |
| 99 | |
| 100 | static void check_all(struct kunit *test) |
| 101 | { |
| 102 | struct xe_guc_id_mgr *idm = test->priv; |
| 103 | unsigned int n; |
| 104 | |
| 105 | KUNIT_ASSERT_EQ(test, 0, xe_guc_id_mgr_init(idm, -1)); |
| 106 | |
| 107 | mutex_lock(idm_mutex(idm)); |
| 108 | |
| 109 | for (n = 0; n < idm->total; n++) |
| 110 | KUNIT_EXPECT_LE(test, 0, idm_reserve_chunk_locked(idm, 1, 0)); |
| 111 | KUNIT_EXPECT_EQ(test, idm->used, idm->total); |
| 112 | for (n = 0; n < idm->total; n++) |
| 113 | idm_release_chunk_locked(idm, n, 1); |
| 114 | |
| 115 | mutex_unlock(lock: idm_mutex(idm)); |
| 116 | } |
| 117 | |
| 118 | static struct kunit_case guc_id_mgr_test_cases[] = { |
| 119 | KUNIT_CASE(bad_init), |
| 120 | KUNIT_CASE(no_init), |
| 121 | KUNIT_CASE(init_fini), |
| 122 | KUNIT_CASE(check_used), |
| 123 | KUNIT_CASE(check_quota), |
| 124 | KUNIT_CASE_SLOW(check_all), |
| 125 | {} |
| 126 | }; |
| 127 | |
| 128 | static struct kunit_suite guc_id_mgr_suite = { |
| 129 | .name = "guc_idm" , |
| 130 | .test_cases = guc_id_mgr_test_cases, |
| 131 | |
| 132 | .init = guc_id_mgr_test_init, |
| 133 | .exit = NULL, |
| 134 | }; |
| 135 | |
| 136 | kunit_test_suites(&guc_id_mgr_suite); |
| 137 | |