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