xref: /linux/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_config_kunit.c (revision 84318277d6334c6981ab326d4acc87c6a6ddc9b8)
1 // SPDX-License-Identifier: GPL-2.0 AND MIT
2 /*
3  * Copyright © 2025 Intel Corporation
4  */
5 
6 #include <kunit/static_stub.h>
7 #include <kunit/test.h>
8 #include <kunit/test-bug.h>
9 
10 #include "xe_kunit_helpers.h"
11 #include "xe_pci_test.h"
12 
13 #define TEST_MAX_VFS	63
14 
15 static void pf_set_admin_mode(struct xe_device *xe, bool enable)
16 {
17 	/* should match logic of xe_sriov_pf_admin_only() */
18 	xe->info.probe_display = !enable;
19 	KUNIT_EXPECT_EQ(kunit_get_current_test(), enable, xe_sriov_pf_admin_only(xe));
20 }
21 
22 static const void *num_vfs_gen_param(struct kunit *test, const void *prev, char *desc)
23 {
24 	unsigned long next = 1 + (unsigned long)prev;
25 
26 	if (next > TEST_MAX_VFS)
27 		return NULL;
28 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%lu VF%s",
29 		 next, str_plural(next));
30 	return (void *)next;
31 }
32 
33 static int pf_gt_config_test_init(struct kunit *test)
34 {
35 	struct xe_pci_fake_data fake = {
36 		.sriov_mode = XE_SRIOV_MODE_PF,
37 		.platform = XE_TIGERLAKE, /* any random platform with SR-IOV */
38 		.subplatform = XE_SUBPLATFORM_NONE,
39 	};
40 	struct xe_device *xe;
41 	struct xe_gt *gt;
42 
43 	test->priv = &fake;
44 	xe_kunit_helper_xe_device_test_init(test);
45 
46 	xe = test->priv;
47 	KUNIT_ASSERT_TRUE(test, IS_SRIOV_PF(xe));
48 
49 	gt = xe_root_mmio_gt(xe);
50 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gt);
51 	test->priv = gt;
52 
53 	/* pretend it can support up to 63 VFs */
54 	xe->sriov.pf.device_total_vfs = TEST_MAX_VFS;
55 	xe->sriov.pf.driver_max_vfs = TEST_MAX_VFS;
56 	KUNIT_ASSERT_EQ(test, xe_sriov_pf_get_totalvfs(xe), 63);
57 
58 	pf_set_admin_mode(xe, false);
59 	KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0);
60 
61 	/* more sanity checks */
62 	KUNIT_EXPECT_EQ(test, GUC_ID_MAX + 1, SZ_64K);
63 	KUNIT_EXPECT_EQ(test, GUC_NUM_DOORBELLS, SZ_256);
64 
65 	return 0;
66 }
67 
68 static void fair_contexts_1vf(struct kunit *test)
69 {
70 	struct xe_gt *gt = test->priv;
71 	struct xe_device *xe = gt_to_xe(gt);
72 
73 	pf_set_admin_mode(xe, false);
74 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
75 	KUNIT_EXPECT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, 1));
76 
77 	pf_set_admin_mode(xe, true);
78 	KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
79 	KUNIT_EXPECT_EQ(test, SZ_64K - SZ_1K, pf_profile_fair_ctxs(gt, 1));
80 }
81 
82 static void fair_contexts(struct kunit *test)
83 {
84 	unsigned int num_vfs = (unsigned long)test->param_value;
85 	struct xe_gt *gt = test->priv;
86 	struct xe_device *xe = gt_to_xe(gt);
87 
88 	pf_set_admin_mode(xe, false);
89 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
90 
91 	KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_ctxs(gt, num_vfs)));
92 	KUNIT_EXPECT_GT(test, GUC_ID_MAX, num_vfs * pf_profile_fair_ctxs(gt, num_vfs));
93 
94 	if (num_vfs > 31)
95 		KUNIT_ASSERT_EQ(test, SZ_1K, pf_profile_fair_ctxs(gt, num_vfs));
96 	else if (num_vfs > 15)
97 		KUNIT_ASSERT_EQ(test, SZ_2K, pf_profile_fair_ctxs(gt, num_vfs));
98 	else if (num_vfs > 7)
99 		KUNIT_ASSERT_EQ(test, SZ_4K, pf_profile_fair_ctxs(gt, num_vfs));
100 	else if (num_vfs > 3)
101 		KUNIT_ASSERT_EQ(test, SZ_8K, pf_profile_fair_ctxs(gt, num_vfs));
102 	else if (num_vfs > 1)
103 		KUNIT_ASSERT_EQ(test, SZ_16K, pf_profile_fair_ctxs(gt, num_vfs));
104 	else
105 		KUNIT_ASSERT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, num_vfs));
106 }
107 
108 static void fair_doorbells_1vf(struct kunit *test)
109 {
110 	struct xe_gt *gt = test->priv;
111 	struct xe_device *xe = gt_to_xe(gt);
112 
113 	pf_set_admin_mode(xe, false);
114 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
115 	KUNIT_EXPECT_EQ(test, 128, pf_profile_fair_dbs(gt, 1));
116 
117 	pf_set_admin_mode(xe, true);
118 	KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
119 	KUNIT_EXPECT_EQ(test, 240, pf_profile_fair_dbs(gt, 1));
120 }
121 
122 static void fair_doorbells(struct kunit *test)
123 {
124 	unsigned int num_vfs = (unsigned long)test->param_value;
125 	struct xe_gt *gt = test->priv;
126 	struct xe_device *xe = gt_to_xe(gt);
127 
128 	pf_set_admin_mode(xe, false);
129 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
130 
131 	KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_dbs(gt, num_vfs)));
132 	KUNIT_EXPECT_GE(test, GUC_NUM_DOORBELLS, (num_vfs + 1) * pf_profile_fair_dbs(gt, num_vfs));
133 
134 	if (num_vfs > 31)
135 		KUNIT_ASSERT_EQ(test, SZ_4, pf_profile_fair_dbs(gt, num_vfs));
136 	else if (num_vfs > 15)
137 		KUNIT_ASSERT_EQ(test, SZ_8, pf_profile_fair_dbs(gt, num_vfs));
138 	else if (num_vfs > 7)
139 		KUNIT_ASSERT_EQ(test, SZ_16, pf_profile_fair_dbs(gt, num_vfs));
140 	else if (num_vfs > 3)
141 		KUNIT_ASSERT_EQ(test, SZ_32, pf_profile_fair_dbs(gt, num_vfs));
142 	else if (num_vfs > 1)
143 		KUNIT_ASSERT_EQ(test, SZ_64, pf_profile_fair_dbs(gt, num_vfs));
144 	else
145 		KUNIT_ASSERT_EQ(test, SZ_128, pf_profile_fair_dbs(gt, num_vfs));
146 }
147 
148 static void fair_ggtt_1vf(struct kunit *test)
149 {
150 	struct xe_gt *gt = test->priv;
151 	struct xe_device *xe = gt_to_xe(gt);
152 
153 	pf_set_admin_mode(xe, false);
154 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
155 	KUNIT_EXPECT_EQ(test, SZ_2G, pf_profile_fair_ggtt(gt, 1));
156 
157 	pf_set_admin_mode(xe, true);
158 	KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
159 	KUNIT_EXPECT_EQ(test, SZ_2G + SZ_1G + SZ_512M, pf_profile_fair_ggtt(gt, 1));
160 }
161 
162 static void fair_ggtt(struct kunit *test)
163 {
164 	unsigned int num_vfs = (unsigned long)test->param_value;
165 	struct xe_gt *gt = test->priv;
166 	struct xe_device *xe = gt_to_xe(gt);
167 	u64 alignment = pf_get_ggtt_alignment(gt);
168 	u64 shareable = SZ_2G + SZ_1G + SZ_512M;
169 
170 	pf_set_admin_mode(xe, false);
171 	KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
172 
173 	KUNIT_EXPECT_TRUE(test, IS_ALIGNED(pf_profile_fair_ggtt(gt, num_vfs), alignment));
174 	KUNIT_EXPECT_GE(test, shareable, num_vfs * pf_profile_fair_ggtt(gt, num_vfs));
175 
176 	if (num_vfs > 56)
177 		KUNIT_ASSERT_EQ(test, SZ_64M - SZ_8M, pf_profile_fair_ggtt(gt, num_vfs));
178 	else if (num_vfs > 28)
179 		KUNIT_ASSERT_EQ(test, SZ_64M, pf_profile_fair_ggtt(gt, num_vfs));
180 	else if (num_vfs > 14)
181 		KUNIT_ASSERT_EQ(test, SZ_128M, pf_profile_fair_ggtt(gt, num_vfs));
182 	else if (num_vfs > 7)
183 		KUNIT_ASSERT_EQ(test, SZ_256M, pf_profile_fair_ggtt(gt, num_vfs));
184 	else if (num_vfs > 3)
185 		KUNIT_ASSERT_EQ(test, SZ_512M, pf_profile_fair_ggtt(gt, num_vfs));
186 	else if (num_vfs > 1)
187 		KUNIT_ASSERT_EQ(test, SZ_1G, pf_profile_fair_ggtt(gt, num_vfs));
188 	else
189 		KUNIT_ASSERT_EQ(test, SZ_2G, pf_profile_fair_ggtt(gt, num_vfs));
190 }
191 
192 static struct kunit_case pf_gt_config_test_cases[] = {
193 	KUNIT_CASE(fair_contexts_1vf),
194 	KUNIT_CASE(fair_doorbells_1vf),
195 	KUNIT_CASE(fair_ggtt_1vf),
196 	KUNIT_CASE_PARAM(fair_contexts, num_vfs_gen_param),
197 	KUNIT_CASE_PARAM(fair_doorbells, num_vfs_gen_param),
198 	KUNIT_CASE_PARAM(fair_ggtt, num_vfs_gen_param),
199 	{}
200 };
201 
202 static struct kunit_suite pf_gt_config_suite = {
203 	.name = "pf_gt_config",
204 	.test_cases = pf_gt_config_test_cases,
205 	.init = pf_gt_config_test_init,
206 };
207 
208 kunit_test_suite(pf_gt_config_suite);
209