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
guc_dbm_test_init(struct kunit * test)11 static 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
test_empty(struct kunit * test)23 static 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
test_default(struct kunit * test)37 static 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
45 static 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
uint_param_get_desc(const unsigned int * p,char * desc)52 static void uint_param_get_desc(const unsigned int *p, char *desc)
53 {
54 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%u", *p);
55 }
56
57 KUNIT_ARRAY_PARAM(guc_dbm, guc_dbm_params, uint_param_get_desc);
58
test_size(struct kunit * test)59 static 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
test_reuse(struct kunit * test)83 static 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
test_range_overlap(struct kunit * test)111 static 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
test_range_compact(struct kunit * test)149 static 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
test_range_spare(struct kunit * test)168 static 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
184 static 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
195 static 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
201 kunit_test_suites(&guc_dbm_suite);
202