]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/tests: Add KUnit tests for PF fair provisioning
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Thu, 6 Nov 2025 16:59:32 +0000 (17:59 +0100)
committerMichal Wajdeczko <michal.wajdeczko@intel.com>
Fri, 7 Nov 2025 18:47:45 +0000 (19:47 +0100)
Add test cases to check outcome of fair GuC context or doorbells
IDs allocations for regular and admin-only PF mode.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
Link: https://patch.msgid.link/20251106165932.2143-1-michal.wajdeczko@intel.com
drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_config_kunit.c [new file with mode: 0644]
drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c

diff --git a/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_config_kunit.c b/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_config_kunit.c
new file mode 100644 (file)
index 0000000..cb3db3e
--- /dev/null
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#include <kunit/static_stub.h>
+#include <kunit/test.h>
+#include <kunit/test-bug.h>
+
+#include "xe_kunit_helpers.h"
+#include "xe_pci_test.h"
+
+#define TEST_MAX_VFS   63
+
+static void pf_set_admin_mode(struct xe_device *xe, bool enable)
+{
+       /* should match logic of xe_sriov_pf_admin_only() */
+       xe->info.probe_display = !enable;
+       KUNIT_EXPECT_EQ(kunit_get_current_test(), enable, xe_sriov_pf_admin_only(xe));
+}
+
+static const void *num_vfs_gen_param(struct kunit *test, const void *prev, char *desc)
+{
+       unsigned long next = 1 + (unsigned long)prev;
+
+       if (next > TEST_MAX_VFS)
+               return NULL;
+       snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%lu VF%s",
+                next, str_plural(next));
+       return (void *)next;
+}
+
+static int pf_gt_config_test_init(struct kunit *test)
+{
+       struct xe_pci_fake_data fake = {
+               .sriov_mode = XE_SRIOV_MODE_PF,
+               .platform = XE_TIGERLAKE, /* any random platform with SR-IOV */
+               .subplatform = XE_SUBPLATFORM_NONE,
+       };
+       struct xe_device *xe;
+       struct xe_gt *gt;
+
+       test->priv = &fake;
+       xe_kunit_helper_xe_device_test_init(test);
+
+       xe = test->priv;
+       KUNIT_ASSERT_TRUE(test, IS_SRIOV_PF(xe));
+
+       gt = xe_root_mmio_gt(xe);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gt);
+       test->priv = gt;
+
+       /* pretend it can support up to 63 VFs */
+       xe->sriov.pf.device_total_vfs = TEST_MAX_VFS;
+       xe->sriov.pf.driver_max_vfs = TEST_MAX_VFS;
+       KUNIT_ASSERT_EQ(test, xe_sriov_pf_get_totalvfs(xe), 63);
+
+       pf_set_admin_mode(xe, false);
+       KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0);
+
+       /* more sanity checks */
+       KUNIT_EXPECT_EQ(test, GUC_ID_MAX + 1, SZ_64K);
+       KUNIT_EXPECT_EQ(test, GUC_NUM_DOORBELLS, SZ_256);
+
+       return 0;
+}
+
+static void fair_contexts_1vf(struct kunit *test)
+{
+       struct xe_gt *gt = test->priv;
+       struct xe_device *xe = gt_to_xe(gt);
+
+       pf_set_admin_mode(xe, false);
+       KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
+       KUNIT_EXPECT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, 1));
+
+       pf_set_admin_mode(xe, true);
+       KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
+       KUNIT_EXPECT_EQ(test, SZ_64K - SZ_1K, pf_profile_fair_ctxs(gt, 1));
+}
+
+static void fair_contexts(struct kunit *test)
+{
+       unsigned int num_vfs = (unsigned long)test->param_value;
+       struct xe_gt *gt = test->priv;
+       struct xe_device *xe = gt_to_xe(gt);
+
+       pf_set_admin_mode(xe, false);
+       KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
+
+       KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_ctxs(gt, num_vfs)));
+       KUNIT_EXPECT_GT(test, GUC_ID_MAX, num_vfs * pf_profile_fair_ctxs(gt, num_vfs));
+
+       if (num_vfs > 31)
+               KUNIT_ASSERT_EQ(test, SZ_1K, pf_profile_fair_ctxs(gt, num_vfs));
+       else if (num_vfs > 15)
+               KUNIT_ASSERT_EQ(test, SZ_2K, pf_profile_fair_ctxs(gt, num_vfs));
+       else if (num_vfs > 7)
+               KUNIT_ASSERT_EQ(test, SZ_4K, pf_profile_fair_ctxs(gt, num_vfs));
+       else if (num_vfs > 3)
+               KUNIT_ASSERT_EQ(test, SZ_8K, pf_profile_fair_ctxs(gt, num_vfs));
+       else if (num_vfs > 1)
+               KUNIT_ASSERT_EQ(test, SZ_16K, pf_profile_fair_ctxs(gt, num_vfs));
+       else
+               KUNIT_ASSERT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, num_vfs));
+}
+
+static void fair_doorbells_1vf(struct kunit *test)
+{
+       struct xe_gt *gt = test->priv;
+       struct xe_device *xe = gt_to_xe(gt);
+
+       pf_set_admin_mode(xe, false);
+       KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
+       KUNIT_EXPECT_EQ(test, 128, pf_profile_fair_dbs(gt, 1));
+
+       pf_set_admin_mode(xe, true);
+       KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
+       KUNIT_EXPECT_EQ(test, 240, pf_profile_fair_dbs(gt, 1));
+}
+
+static void fair_doorbells(struct kunit *test)
+{
+       unsigned int num_vfs = (unsigned long)test->param_value;
+       struct xe_gt *gt = test->priv;
+       struct xe_device *xe = gt_to_xe(gt);
+
+       pf_set_admin_mode(xe, false);
+       KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
+
+       KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_dbs(gt, num_vfs)));
+       KUNIT_EXPECT_GE(test, GUC_NUM_DOORBELLS, (num_vfs + 1) * pf_profile_fair_dbs(gt, num_vfs));
+
+       if (num_vfs > 31)
+               KUNIT_ASSERT_EQ(test, SZ_4, pf_profile_fair_dbs(gt, num_vfs));
+       else if (num_vfs > 15)
+               KUNIT_ASSERT_EQ(test, SZ_8, pf_profile_fair_dbs(gt, num_vfs));
+       else if (num_vfs > 7)
+               KUNIT_ASSERT_EQ(test, SZ_16, pf_profile_fair_dbs(gt, num_vfs));
+       else if (num_vfs > 3)
+               KUNIT_ASSERT_EQ(test, SZ_32, pf_profile_fair_dbs(gt, num_vfs));
+       else if (num_vfs > 1)
+               KUNIT_ASSERT_EQ(test, SZ_64, pf_profile_fair_dbs(gt, num_vfs));
+       else
+               KUNIT_ASSERT_EQ(test, SZ_128, pf_profile_fair_dbs(gt, num_vfs));
+}
+
+static struct kunit_case pf_gt_config_test_cases[] = {
+       KUNIT_CASE(fair_contexts_1vf),
+       KUNIT_CASE(fair_doorbells_1vf),
+       KUNIT_CASE_PARAM(fair_contexts, num_vfs_gen_param),
+       KUNIT_CASE_PARAM(fair_doorbells, num_vfs_gen_param),
+       {}
+};
+
+static struct kunit_suite pf_gt_config_suite = {
+       .name = "pf_gt_config",
+       .test_cases = pf_gt_config_test_cases,
+       .init = pf_gt_config_test_init,
+};
+
+kunit_test_suite(pf_gt_config_suite);
index 701889e5ddedc964589b6a36b9e395597dacf04a..80cc3f2cd047dececc33c5743e2d8b234eeead98 100644 (file)
@@ -2826,3 +2826,7 @@ int xe_gt_sriov_pf_config_print_available_ggtt(struct xe_gt *gt, struct drm_prin
 
        return 0;
 }
+
+#if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST)
+#include "tests/xe_gt_sriov_pf_config_kunit.c"
+#endif