1// SPDX-License-Identifier: GPL-2.0 AND MIT 2/* 3 * Copyright �� 2023 Intel Corporation 4 */ 5 6#include <kunit/test.h> 7 8#include "xe_device.h" 9#include "xe_kunit_helpers.h" 10 11static int guc_dbm_test_init(struct kunit *test) 12{ 13 struct xe_guc_db_mgr *dbm; 14 15 xe_kunit_helper_xe_device_test_init(test); 16 dbm = &xe_device_get_gt(test->priv, 0)->uc.guc.dbm; 17 18 mutex_init(dbm_mutex(dbm)); 19 test->priv = dbm; 20 return 0; 21} 22 23static void test_empty(struct kunit *test) 24{ 25 struct xe_guc_db_mgr *dbm = test->priv; 26 27 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, 0), 0); 28 KUNIT_ASSERT_EQ(test, dbm->count, 0); 29 30 mutex_lock(dbm_mutex(dbm)); 31 KUNIT_EXPECT_LT(test, xe_guc_db_mgr_reserve_id_locked(dbm), 0); 32 mutex_unlock(dbm_mutex(dbm)); 33 34 KUNIT_EXPECT_LT(test, xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 35} 36 37static void test_default(struct kunit *test) 38{ 39 struct xe_guc_db_mgr *dbm = test->priv; 40 41 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, ~0), 0); 42 KUNIT_ASSERT_EQ(test, dbm->count, GUC_NUM_DOORBELLS); 43} 44 45static const unsigned int guc_dbm_params[] = { 46 GUC_NUM_DOORBELLS / 64, 47 GUC_NUM_DOORBELLS / 32, 48 GUC_NUM_DOORBELLS / 8, 49 GUC_NUM_DOORBELLS, 50}; 51 52static void uint_param_get_desc(const unsigned int *p, char *desc) 53{ 54 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%u", *p); 55} 56 57KUNIT_ARRAY_PARAM(guc_dbm, guc_dbm_params, uint_param_get_desc); 58 59static void test_size(struct kunit *test) 60{ 61 const unsigned int *p = test->param_value; 62 struct xe_guc_db_mgr *dbm = test->priv; 63 unsigned int n; 64 int id; 65 66 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, *p), 0); 67 KUNIT_ASSERT_EQ(test, dbm->count, *p); 68 69 mutex_lock(dbm_mutex(dbm)); 70 for (n = 0; n < *p; n++) { 71 KUNIT_EXPECT_GE(test, id = xe_guc_db_mgr_reserve_id_locked(dbm), 0); 72 KUNIT_EXPECT_LT(test, id, dbm->count); 73 } 74 KUNIT_EXPECT_LT(test, xe_guc_db_mgr_reserve_id_locked(dbm), 0); 75 mutex_unlock(dbm_mutex(dbm)); 76 77 mutex_lock(dbm_mutex(dbm)); 78 for (n = 0; n < *p; n++) 79 xe_guc_db_mgr_release_id_locked(dbm, n); 80 mutex_unlock(dbm_mutex(dbm)); 81} 82 83static void test_reuse(struct kunit *test) 84{ 85 const unsigned int *p = test->param_value; 86 struct xe_guc_db_mgr *dbm = test->priv; 87 unsigned int n; 88 89 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, *p), 0); 90 91 mutex_lock(dbm_mutex(dbm)); 92 for (n = 0; n < *p; n++) 93 KUNIT_EXPECT_GE(test, xe_guc_db_mgr_reserve_id_locked(dbm), 0); 94 KUNIT_EXPECT_LT(test, xe_guc_db_mgr_reserve_id_locked(dbm), 0); 95 mutex_unlock(dbm_mutex(dbm)); 96 97 mutex_lock(dbm_mutex(dbm)); 98 for (n = 0; n < *p; n++) { 99 xe_guc_db_mgr_release_id_locked(dbm, n); 100 KUNIT_EXPECT_EQ(test, xe_guc_db_mgr_reserve_id_locked(dbm), n); 101 } 102 KUNIT_EXPECT_LT(test, xe_guc_db_mgr_reserve_id_locked(dbm), 0); 103 mutex_unlock(dbm_mutex(dbm)); 104 105 mutex_lock(dbm_mutex(dbm)); 106 for (n = 0; n < *p; n++) 107 xe_guc_db_mgr_release_id_locked(dbm, n); 108 mutex_unlock(dbm_mutex(dbm)); 109} 110 111static void test_range_overlap(struct kunit *test) 112{ 113 const unsigned int *p = test->param_value; 114 struct xe_guc_db_mgr *dbm = test->priv; 115 int id1, id2, id3; 116 unsigned int n; 117 118 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, ~0), 0); 119 KUNIT_ASSERT_LE(test, *p, dbm->count); 120 121 KUNIT_ASSERT_GE(test, id1 = xe_guc_db_mgr_reserve_range(dbm, *p, 0), 0); 122 for (n = 0; n < dbm->count - *p; n++) { 123 KUNIT_ASSERT_GE(test, id2 = xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 124 KUNIT_ASSERT_NE(test, id2, id1); 125 KUNIT_ASSERT_NE_MSG(test, id2 < id1, id2 > id1 + *p - 1, 126 "id1=%d id2=%d", id1, id2); 127 } 128 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 129 xe_guc_db_mgr_release_range(dbm, 0, dbm->count); 130 131 if (*p >= 1) { 132 KUNIT_ASSERT_GE(test, id1 = xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 133 KUNIT_ASSERT_GE(test, id2 = xe_guc_db_mgr_reserve_range(dbm, *p - 1, 0), 0); 134 KUNIT_ASSERT_NE(test, id2, id1); 135 KUNIT_ASSERT_NE_MSG(test, id1 < id2, id1 > id2 + *p - 2, 136 "id1=%d id2=%d", id1, id2); 137 for (n = 0; n < dbm->count - *p; n++) { 138 KUNIT_ASSERT_GE(test, id3 = xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 139 KUNIT_ASSERT_NE(test, id3, id1); 140 KUNIT_ASSERT_NE(test, id3, id2); 141 KUNIT_ASSERT_NE_MSG(test, id3 < id2, id3 > id2 + *p - 2, 142 "id3=%d id2=%d", id3, id2); 143 } 144 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 145 xe_guc_db_mgr_release_range(dbm, 0, dbm->count); 146 } 147} 148 149static void test_range_compact(struct kunit *test) 150{ 151 const unsigned int *p = test->param_value; 152 struct xe_guc_db_mgr *dbm = test->priv; 153 unsigned int n; 154 155 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, ~0), 0); 156 KUNIT_ASSERT_NE(test, *p, 0); 157 KUNIT_ASSERT_LE(test, *p, dbm->count); 158 if (dbm->count % *p) 159 kunit_skip(test, "must be divisible"); 160 161 KUNIT_ASSERT_GE(test, xe_guc_db_mgr_reserve_range(dbm, *p, 0), 0); 162 for (n = 1; n < dbm->count / *p; n++) 163 KUNIT_ASSERT_GE(test, xe_guc_db_mgr_reserve_range(dbm, *p, 0), 0); 164 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, 1, 0), 0); 165 xe_guc_db_mgr_release_range(dbm, 0, dbm->count); 166} 167 168static void test_range_spare(struct kunit *test) 169{ 170 const unsigned int *p = test->param_value; 171 struct xe_guc_db_mgr *dbm = test->priv; 172 int id; 173 174 KUNIT_ASSERT_EQ(test, xe_guc_db_mgr_init(dbm, ~0), 0); 175 KUNIT_ASSERT_LE(test, *p, dbm->count); 176 177 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, *p, dbm->count), 0); 178 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, *p, dbm->count - *p + 1), 0); 179 KUNIT_ASSERT_EQ(test, id = xe_guc_db_mgr_reserve_range(dbm, *p, dbm->count - *p), 0); 180 KUNIT_ASSERT_LT(test, xe_guc_db_mgr_reserve_range(dbm, 1, dbm->count - *p), 0); 181 xe_guc_db_mgr_release_range(dbm, id, *p); 182} 183 184static struct kunit_case guc_dbm_test_cases[] = { 185 KUNIT_CASE(test_empty), 186 KUNIT_CASE(test_default), 187 KUNIT_CASE_PARAM(test_size, guc_dbm_gen_params), 188 KUNIT_CASE_PARAM(test_reuse, guc_dbm_gen_params), 189 KUNIT_CASE_PARAM(test_range_overlap, guc_dbm_gen_params), 190 KUNIT_CASE_PARAM(test_range_compact, guc_dbm_gen_params), 191 KUNIT_CASE_PARAM(test_range_spare, guc_dbm_gen_params), 192 {} 193}; 194 195static struct kunit_suite guc_dbm_suite = { 196 .name = "guc_dbm", 197 .test_cases = guc_dbm_test_cases, 198 .init = guc_dbm_test_init, 199}; 200 201kunit_test_suites(&guc_dbm_suite); 202