Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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);