From: Michal Wajdeczko <michal.wajdeczko@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>,
Lucas De Marchi <lucas.demarchi@intel.com>
Subject: [PATCH v2 11/12] drm/xe/tests: Add KUnit tests for VF control state machines
Date: Fri, 9 Aug 2024 19:23:15 +0200 [thread overview]
Message-ID: <20240809172315.749-1-michal.wajdeczko@intel.com> (raw)
In-Reply-To: <20240809165159.662-12-michal.wajdeczko@intel.com>
Add KUnit tests (~200) for all VF control state machines (FLR,
PAUSE, STOP and RESUME) to make sure they work as expected and
will not be broken while extending them with new functionality.
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
---
Test file named according to the new best practices [1]
[1] https://lore.kernel.org/linux-hardening/20240724201354.make.730-kees@kernel.org/
---
v2: fix kunit build break due last-minute change in .c
---
.../xe/tests/xe_gt_sriov_pf_control_kunit.c | 1360 +++++++++++++++++
drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 7 +
2 files changed, 1367 insertions(+)
create mode 100644 drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_control_kunit.c
diff --git a/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_control_kunit.c b/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_control_kunit.c
new file mode 100644
index 000000000000..3061099ad35a
--- /dev/null
+++ b/drivers/gpu/drm/xe/tests/xe_gt_sriov_pf_control_kunit.c
@@ -0,0 +1,1360 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <kunit/test.h>
+#include <kunit/static_stub.h>
+
+#include "tests/xe_kunit_helpers.h"
+#include "tests/xe_pci_test.h"
+
+#include "xe_gt_sriov_pf.h"
+
+static const unsigned int DUT_NUM_VFS = 2;
+static const unsigned int VFUT1 = VFID(1);
+static const unsigned int VFUT2 = VFID(2);
+
+static void dump_state(void *arg)
+{
+ struct xe_gt *gt = arg;
+
+ pf_dump_vf_state(gt, VFUT1);
+}
+
+static unsigned long replacement_timeout(enum xe_gt_sriov_control_bits bit)
+{
+ return HZ;
+}
+
+static int pf_control_test_init(struct kunit *test)
+{
+ struct xe_pci_fake_data fake = {
+ .sriov_mode = XE_SRIOV_MODE_PF,
+ .platform = XE_TIGERLAKE, /* some random platform */
+ .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_EQ(test, xe_sriov_init(xe), 0);
+
+ xe->sriov.pf.driver_max_vfs = DUT_NUM_VFS;
+ KUNIT_EXPECT_NE(test, xe_sriov_pf_get_totalvfs(xe), 0);
+
+ gt = xe_device_get_gt(xe, 0);
+ KUNIT_ASSERT_EQ(test, xe_gt_sriov_pf_init_early(gt), 0);
+
+ KUNIT_ASSERT_EQ(test, 0ul, *pf_peek_vf_state(gt, VFUT1));
+ KUNIT_ASSERT_EQ(test, 0ul, *pf_peek_vf_state(gt, VFUT2));
+
+ KUNIT_EXPECT_EQ(test, 0, kunit_add_action_or_reset(test, dump_state, gt));
+
+ kunit_activate_static_stub(test, pf_get_default_timeout, replacement_timeout);
+
+ test->priv = gt;
+ return 0;
+}
+
+static int sanitize_vf_resources_fail(struct xe_gt *gt, u32 vfid, long timeout)
+{
+ return -ETIMEDOUT;
+}
+
+static int send_vf_control_cmd_reject(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return -EIO;
+}
+
+static int send_vf_control_cmd_fail(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return -ENODEV;
+}
+
+static int send_vf_control_cmd_pass_no_reply(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return 0;
+}
+
+static int send_vf_control_cmd_pass_and_reply(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ switch (cmd) {
+ case GUC_PF_TRIGGER_VF_PAUSE:
+ pf_handle_vf_event(gt, vfid, GUC_PF_NOTIFY_VF_PAUSE_DONE);
+ break;
+ case GUC_PF_TRIGGER_VF_FLR_START:
+ pf_handle_vf_event(gt, vfid, GUC_PF_NOTIFY_VF_FLR_DONE);
+ break;
+ case GUC_PF_TRIGGER_VF_RESUME:
+ case GUC_PF_TRIGGER_VF_STOP:
+ case GUC_PF_TRIGGER_VF_FLR_FINISH:
+ break;
+ default:
+ return -EPROTO;
+ }
+ return 0;
+}
+
+static int send_vf_control_cmd_busy_wait(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ schedule_timeout_interruptible(HZ / 20);
+ return -EBUSY;
+}
+
+static int send_vf_control_cmd_pass_but_reply_flr_only(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return cmd == GUC_PF_TRIGGER_VF_FLR_START ?
+ send_vf_control_cmd_pass_and_reply(gt, vfid, cmd) :
+ send_vf_control_cmd_pass_no_reply(gt, vfid, cmd);
+}
+
+static int send_vf_control_cmd_busy_except_flr(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return cmd == GUC_PF_TRIGGER_VF_FLR_START || cmd == GUC_PF_TRIGGER_VF_FLR_FINISH ?
+ send_vf_control_cmd_pass_and_reply(gt, vfid, cmd) :
+ send_vf_control_cmd_busy_wait(gt, vfid, cmd);
+}
+
+static int send_vf_control_cmd_busy_except_stop(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ return cmd == GUC_PF_TRIGGER_VF_STOP ?
+ send_vf_control_cmd_pass_and_reply(gt, vfid, cmd) :
+ send_vf_control_cmd_busy_wait(gt, vfid, cmd);
+}
+
+static int BUSY_MAGIC = 3;
+
+static int send_vf_control_cmd_busy_no_reply(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ static int counter;
+
+ return ++counter % BUSY_MAGIC ? -EBUSY : 0;
+}
+
+static int send_vf_control_cmd_busy_and_reply(struct xe_gt *gt, unsigned int vfid, u32 cmd)
+{
+ static int counter;
+
+ return ++counter % BUSY_MAGIC ? -EBUSY :
+ send_vf_control_cmd_pass_and_reply(gt, vfid, cmd);
+}
+
+static const enum xe_gt_sriov_control_bits ready[] = {
+};
+
+static const enum xe_gt_sriov_control_bits flr_starting[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_SEND_START,
+};
+
+static const enum xe_gt_sriov_control_bits flr_starting_paused[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_SEND_START,
+ XE_GT_SRIOV_STATE_PAUSED,
+};
+
+static const enum xe_gt_sriov_control_bits flr_starting_stopped[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_SEND_START,
+ XE_GT_SRIOV_STATE_STOPPED,
+};
+
+static const enum xe_gt_sriov_control_bits flr_waiting[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_WAIT_GUC,
+};
+
+static const enum xe_gt_sriov_control_bits flr_guc_done[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_GUC_DONE,
+};
+
+static const enum xe_gt_sriov_control_bits flr_resetting[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_RESET_CONFIG,
+};
+
+static const enum xe_gt_sriov_control_bits flr_finishing[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_SEND_FINISH,
+};
+
+static const enum xe_gt_sriov_control_bits flr_failed[] = {
+ XE_GT_SRIOV_STATE_FLR_FAILED,
+};
+
+static const enum xe_gt_sriov_control_bits stopping[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_STOP_WIP,
+ XE_GT_SRIOV_STATE_STOP_SEND_STOP,
+};
+
+static const enum xe_gt_sriov_control_bits stopping_paused[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_STOP_WIP,
+ XE_GT_SRIOV_STATE_STOP_SEND_STOP,
+ XE_GT_SRIOV_STATE_PAUSED,
+};
+
+static const enum xe_gt_sriov_control_bits stop_failed[] = {
+ XE_GT_SRIOV_STATE_STOP_FAILED,
+};
+
+static const enum xe_gt_sriov_control_bits stop_rejected[] = {
+ XE_GT_SRIOV_STATE_STOP_FAILED,
+ XE_GT_SRIOV_STATE_MISMATCH,
+};
+
+static const enum xe_gt_sriov_control_bits stopped[] = {
+ XE_GT_SRIOV_STATE_STOPPED,
+};
+
+static const enum xe_gt_sriov_control_bits pausing[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE,
+};
+
+static const enum xe_gt_sriov_control_bits pausing_wait_guc[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC,
+};
+
+static const enum xe_gt_sriov_control_bits pausing_guc_done[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_WIP,
+ XE_GT_SRIOV_STATE_PAUSE_GUC_DONE,
+};
+
+static const enum xe_gt_sriov_control_bits pause_failed[] = {
+ XE_GT_SRIOV_STATE_PAUSE_FAILED,
+};
+
+static const enum xe_gt_sriov_control_bits pause_rejected[] = {
+ XE_GT_SRIOV_STATE_PAUSE_FAILED,
+ XE_GT_SRIOV_STATE_MISMATCH,
+};
+
+static const enum xe_gt_sriov_control_bits paused[] = {
+ XE_GT_SRIOV_STATE_PAUSED,
+};
+
+static const enum xe_gt_sriov_control_bits resuming[] = {
+ XE_GT_SRIOV_STATE_WIP,
+ XE_GT_SRIOV_STATE_PAUSED,
+ XE_GT_SRIOV_STATE_RESUME_WIP,
+ XE_GT_SRIOV_STATE_RESUME_SEND_RESUME,
+};
+
+static const enum xe_gt_sriov_control_bits resume_failed[] = {
+ XE_GT_SRIOV_STATE_PAUSED,
+ XE_GT_SRIOV_STATE_RESUME_FAILED,
+};
+
+static const enum xe_gt_sriov_control_bits resume_rejected[] = {
+ XE_GT_SRIOV_STATE_PAUSED,
+ XE_GT_SRIOV_STATE_RESUME_FAILED,
+ XE_GT_SRIOV_STATE_MISMATCH,
+};
+
+static const enum xe_gt_sriov_control_bits resumed[] = {
+ XE_GT_SRIOV_STATE_RESUMED,
+};
+
+static const enum xe_gt_sriov_control_bits mismatch[] = {
+ XE_GT_SRIOV_STATE_MISMATCH,
+};
+
+struct state_param {
+ const char *name;
+ const enum xe_gt_sriov_control_bits *bits;
+ size_t num_bits;
+};
+
+static void state_param_get_desc(struct state_param *p, char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", p->name);
+}
+
+#define MAKE_STATE_PARAM(X) { .name = #X, .bits = X, .num_bits = ARRAY_SIZE(X) }
+
+/*
+ * Due to the test case logic the all "must_pass" params include "_rejected" states
+ * since our "GuC" calls by default will not complain again about the INVALID_STATE
+ * thus our state machine is able to fully recover.
+ */
+
+static struct state_param flr_must_pass_from[] = {
+ MAKE_STATE_PARAM(ready),
+ MAKE_STATE_PARAM(flr_starting),
+ MAKE_STATE_PARAM(flr_starting_paused),
+ MAKE_STATE_PARAM(flr_starting_stopped),
+ MAKE_STATE_PARAM(flr_waiting),
+ MAKE_STATE_PARAM(flr_guc_done),
+ MAKE_STATE_PARAM(flr_resetting),
+ MAKE_STATE_PARAM(flr_finishing),
+ MAKE_STATE_PARAM(flr_failed),
+ MAKE_STATE_PARAM(stopping),
+ MAKE_STATE_PARAM(stop_failed),
+ MAKE_STATE_PARAM(stop_rejected),
+ MAKE_STATE_PARAM(stopped),
+ MAKE_STATE_PARAM(pausing),
+ MAKE_STATE_PARAM(pausing_wait_guc),
+ MAKE_STATE_PARAM(pausing_guc_done),
+ MAKE_STATE_PARAM(pause_failed),
+ MAKE_STATE_PARAM(pause_rejected),
+ MAKE_STATE_PARAM(paused),
+ MAKE_STATE_PARAM(resuming),
+ MAKE_STATE_PARAM(resume_failed),
+ MAKE_STATE_PARAM(resume_rejected),
+ MAKE_STATE_PARAM(resumed),
+ MAKE_STATE_PARAM(mismatch),
+};
+
+static struct state_param stop_must_pass_from[] = {
+ MAKE_STATE_PARAM(ready),
+ MAKE_STATE_PARAM(stop_failed),
+ MAKE_STATE_PARAM(stop_rejected),
+ MAKE_STATE_PARAM(pausing),
+ MAKE_STATE_PARAM(pausing_wait_guc),
+ MAKE_STATE_PARAM(pausing_guc_done),
+ MAKE_STATE_PARAM(pause_failed),
+ MAKE_STATE_PARAM(pause_rejected),
+ MAKE_STATE_PARAM(paused),
+ MAKE_STATE_PARAM(resuming),
+ MAKE_STATE_PARAM(resume_failed),
+ MAKE_STATE_PARAM(resume_rejected),
+ MAKE_STATE_PARAM(resumed),
+ MAKE_STATE_PARAM(mismatch),
+ MAKE_STATE_PARAM(flr_failed),
+};
+
+static struct state_param stop_must_cancel_from[] = {
+ MAKE_STATE_PARAM(flr_starting),
+ MAKE_STATE_PARAM(flr_starting_paused),
+ MAKE_STATE_PARAM(flr_waiting),
+ MAKE_STATE_PARAM(flr_guc_done),
+ MAKE_STATE_PARAM(flr_resetting),
+ MAKE_STATE_PARAM(flr_finishing),
+};
+
+static struct state_param stop_must_fail_from[] = {
+ MAKE_STATE_PARAM(stopping),
+ MAKE_STATE_PARAM(stopping_paused),
+ MAKE_STATE_PARAM(stopped),
+ MAKE_STATE_PARAM(flr_starting_stopped),
+};
+
+static struct state_param pause_must_pass_from[] = {
+ MAKE_STATE_PARAM(ready),
+ MAKE_STATE_PARAM(pause_failed),
+ MAKE_STATE_PARAM(pause_rejected),
+ MAKE_STATE_PARAM(resumed),
+ MAKE_STATE_PARAM(mismatch),
+ MAKE_STATE_PARAM(stop_failed),
+ MAKE_STATE_PARAM(stop_rejected),
+ MAKE_STATE_PARAM(flr_failed),
+};
+
+static struct state_param pause_must_cancel_from[] = {
+ MAKE_STATE_PARAM(flr_starting),
+ MAKE_STATE_PARAM(flr_waiting),
+ MAKE_STATE_PARAM(flr_guc_done),
+ MAKE_STATE_PARAM(flr_resetting),
+ MAKE_STATE_PARAM(flr_finishing),
+ MAKE_STATE_PARAM(stopping),
+};
+
+static struct state_param pause_must_fail_from[] = {
+ MAKE_STATE_PARAM(pausing),
+ MAKE_STATE_PARAM(pausing_wait_guc),
+ MAKE_STATE_PARAM(pausing_guc_done),
+ MAKE_STATE_PARAM(paused),
+ MAKE_STATE_PARAM(resuming),
+ MAKE_STATE_PARAM(resume_failed),
+ MAKE_STATE_PARAM(resume_rejected),
+ MAKE_STATE_PARAM(stopped),
+};
+
+static struct state_param resume_must_pass_from[] = {
+ MAKE_STATE_PARAM(paused),
+ MAKE_STATE_PARAM(resume_failed),
+ MAKE_STATE_PARAM(resume_rejected),
+};
+
+static struct state_param resume_must_cancel_from[] = {
+ MAKE_STATE_PARAM(flr_starting_paused),
+ MAKE_STATE_PARAM(stopping_paused),
+};
+
+static struct state_param resume_must_fail_from[] = {
+ MAKE_STATE_PARAM(ready),
+ MAKE_STATE_PARAM(pausing),
+ MAKE_STATE_PARAM(pausing_wait_guc),
+ MAKE_STATE_PARAM(pausing_guc_done),
+ MAKE_STATE_PARAM(pause_failed),
+ MAKE_STATE_PARAM(pause_rejected),
+ MAKE_STATE_PARAM(resuming),
+ MAKE_STATE_PARAM(resumed),
+ MAKE_STATE_PARAM(stopping),
+ MAKE_STATE_PARAM(stop_failed),
+ MAKE_STATE_PARAM(stop_rejected),
+ MAKE_STATE_PARAM(stopped),
+ MAKE_STATE_PARAM(flr_starting),
+ MAKE_STATE_PARAM(flr_waiting),
+ MAKE_STATE_PARAM(flr_guc_done),
+ MAKE_STATE_PARAM(flr_resetting),
+ MAKE_STATE_PARAM(flr_finishing),
+ MAKE_STATE_PARAM(flr_failed),
+ MAKE_STATE_PARAM(mismatch),
+};
+
+KUNIT_ARRAY_PARAM(flr_must_pass_from, flr_must_pass_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(stop_must_pass_from, stop_must_pass_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(stop_must_fail_from, stop_must_fail_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(stop_must_cancel_from, stop_must_cancel_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(pause_must_pass_from, pause_must_pass_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(pause_must_fail_from, pause_must_fail_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(pause_must_cancel_from, pause_must_cancel_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(resume_must_pass_from, resume_must_pass_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(resume_must_fail_from, resume_must_fail_from, state_param_get_desc);
+KUNIT_ARRAY_PARAM(resume_must_cancel_from, resume_must_cancel_from, state_param_get_desc);
+
+static int mimic_pf_handle_vf_flr_done(struct xe_gt *gt, unsigned int vfid)
+{
+ pf_handle_vf_flr_done(gt, vfid);
+ return 0;
+}
+
+static int mimic_pf_handle_vf_pause_done(struct xe_gt *gt, unsigned int vfid)
+{
+ pf_handle_vf_pause_done(gt, vfid);
+ return 0;
+}
+
+static void prepare_state(struct kunit *test, unsigned int vfid,
+ const enum xe_gt_sriov_control_bits *bits, size_t num_bits)
+{
+ struct xe_gt *gt = test->priv;
+ size_t n;
+
+ for (n = 0; n < num_bits; n++) {
+ enum xe_gt_sriov_control_bits bit = bits[n];
+
+ KUNIT_ASSERT_TRUE(test, pf_enter_vf_state(gt, vfid, bit));
+
+ if (bit == XE_GT_SRIOV_STATE_WIP) {
+ pf_queue_vf(gt, vfid);
+ } else if (bit == XE_GT_SRIOV_STATE_FLR_WAIT_GUC) {
+ xe_kunit_helper_delayed_call(test, HZ / 100,
+ mimic_pf_handle_vf_flr_done, gt, vfid);
+ } else if (bit == XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC) {
+ xe_kunit_helper_delayed_call(test, HZ / 100,
+ mimic_pf_handle_vf_pause_done, gt, vfid);
+ }
+ }
+}
+
+static void prepare_state_from_param(struct kunit *test)
+{
+ const struct state_param *p = test->param_value;
+
+ prepare_state(test, VFUT1, p->bits, p->num_bits);
+}
+
+static void expect_not_pausing(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WIP));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_GUC_DONE));
+}
+
+static void expect_not_in_pause(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ expect_not_pausing(test);
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_FAILED));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+}
+
+static void expect_not_resuming(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_WIP));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_SEND_RESUME));
+}
+
+static void expect_not_in_resume(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ expect_not_resuming(test);
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_FAILED));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+}
+
+static void expect_not_stopping(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_WIP));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_SEND_STOP));
+}
+
+static void expect_not_in_stop(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ expect_not_stopping(test);
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_FAILED));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOPPED));
+}
+
+static void expect_not_in_flr(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_SEND_START));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WAIT_GUC));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_GUC_DONE));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_SEND_FINISH));
+ KUNIT_EXPECT_TRUE(test,
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+}
+
+static void expect_not_in_wip(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void expect_not_in_mismatch(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+}
+
+static void try_flr_vf(struct kunit *test, bool mimic_busy, bool late_reply)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ mimic_busy ? late_reply ? send_vf_control_cmd_busy_no_reply :
+ send_vf_control_cmd_busy_and_reply :
+ late_reply ? send_vf_control_cmd_pass_no_reply :
+ send_vf_control_cmd_pass_and_reply);
+
+ if (late_reply)
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ mimic_pf_handle_vf_flr_done, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+
+ expect_not_in_flr(test);
+ expect_not_in_pause(test);
+ expect_not_in_resume(test);
+ expect_not_in_stop(test);
+ expect_not_in_mismatch(test);
+ expect_not_in_wip(test);
+}
+
+static void flr_vf_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_flr_vf(test, false, false);
+}
+
+static void flr_vf_needs_retry_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_flr_vf(test, true, false);
+}
+
+static void flr_vf_needs_retry_late_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_flr_vf(test, true, true);
+}
+
+static void flr_vf_fails_on_send(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_fail);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ETIMEDOUT);
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void flr_vf_fails_on_reset(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.vfs[VFUT1].config.sanitize,
+ sanitize_vf_resources_fail);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ETIMEDOUT);
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void flr_vf_rejected_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_reject);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ETIMEDOUT);
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void flr_vf_unconfirmed_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, err, -ETIMEDOUT);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+}
+
+static void flr_vf_confirmed_early_continue_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, flr_starting, ARRAY_SIZE(flr_starting));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ pf_handle_vf_flr_done(gt, VFUT1);
+
+ /*
+ * make sure SEND_START completes;
+ * successful reply from cmd_pass_no_reply should exit mismatch state
+ */
+ flush_work(>->sriov.pf.control.worker);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+}
+
+static void flr_vf_confirmed_early_reject_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, flr_starting, ARRAY_SIZE(flr_starting));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_reject);
+
+ pf_handle_vf_flr_done(gt, VFUT1);
+
+ /*
+ * make sure SEND_START completes;
+ * error from send_vf_control_cmd_reject should keep mismatch state
+ */
+ flush_work(>->sriov.pf.control.worker);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void flr_vf_confirmed_twice_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, flr_guc_done, ARRAY_SIZE(flr_guc_done));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ pf_handle_vf_flr_done(gt, VFUT1);
+
+ /* this is fully recoverable */
+ KUNIT_EXPECT_EQ(test, 0, pf_wait_vf_wip_done(gt, VFUT1, HZ));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+}
+
+static void flr_vf_confirmed_too_late_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, flr_failed, ARRAY_SIZE(flr_failed));
+
+ pf_handle_vf_flr_done(gt, VFUT1);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void flr_vf_unsolicited_confirmation_from_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+
+ pf_handle_vf_flr_done(gt, VFUT1);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_FLR_FAILED));
+}
+
+static void flr_vf_wrong_confirmation_from_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, flr_waiting, ARRAY_SIZE(flr_waiting));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ pf_handle_vf_pause_done(gt, VFUT1);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+}
+
+static void flr_vf_canceled_by_restart(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_wait);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10, xe_gt_sriov_pf_control_restart, gt);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ expect_not_in_flr(test);
+}
+
+static void try_stop_vf(struct kunit *test, bool mimic_busy)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ mimic_busy ? send_vf_control_cmd_busy_and_reply :
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOPPED));
+ expect_not_stopping(test);
+ expect_not_in_pause(test);
+ expect_not_in_resume(test);
+ expect_not_in_mismatch(test);
+}
+
+static void stop_vf_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_stop_vf(test, false);
+}
+
+static void stop_vf_needs_retry_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_stop_vf(test, true);
+}
+
+static void stop_vf_refused_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, err == -EALREADY ||
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_FAILED));
+}
+
+static void stop_vf_fails_on_send(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_fail);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ETIMEDOUT);
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_FAILED));
+ expect_not_stopping(test);
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOPPED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void stop_vf_rejected_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_reject);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ETIMEDOUT);
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ expect_not_stopping(test);
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOPPED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void stop_vf_canceled_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOP_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_STOPPED));
+}
+
+static void stop_vf_canceled_by_restart(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_except_flr);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10, xe_gt_sriov_pf_control_restart, gt);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ expect_not_in_stop(test);
+}
+
+static void stop_vf_canceled_by_flr(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_except_flr);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ xe_gt_sriov_pf_control_trigger_flr, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ expect_not_in_stop(test);
+}
+
+static void try_pause_vf(struct kunit *test, bool mimic_busy)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ mimic_busy ? send_vf_control_cmd_busy_and_reply :
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ expect_not_pausing(test);
+ expect_not_in_mismatch(test);
+}
+
+static void pause_vf_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_pause_vf(test, false);
+}
+
+static void pause_vf_needs_retry_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_pause_vf(test, true);
+}
+
+static void pause_vf_canceled_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ expect_not_in_pause(test);
+}
+
+static void pause_vf_refused_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -ECANCELED);
+
+ KUNIT_EXPECT_TRUE(test, err == -EALREADY ||
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_FAILED));
+}
+
+static void pause_vf_rejected_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_reject);
+
+ KUNIT_EXPECT_NE(test, 0, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void pause_vf_fails_on_send(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_fail);
+
+ KUNIT_EXPECT_NE(test, 0, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_FAILED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_WIP));
+}
+
+static void pause_vf_unconfirmed_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, err, -ETIMEDOUT);
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSE_FAILED));
+}
+
+static void pause_vf_canceled_by_restart(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10, xe_gt_sriov_pf_control_restart, gt);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ expect_not_in_pause(test);
+}
+
+static void pause_vf_canceled_by_flr(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_but_reply_flr_only);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ xe_gt_sriov_pf_control_trigger_flr, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ expect_not_in_pause(test);
+}
+
+static void pause_vf_canceled_by_stop(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_no_reply);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ xe_gt_sriov_pf_control_stop_vf, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ expect_not_in_pause(test);
+}
+
+static void try_resume_vf(struct kunit *test, bool mimic_busy)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ mimic_busy ? send_vf_control_cmd_busy_and_reply :
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+ expect_not_resuming(test);
+ expect_not_in_pause(test);
+ expect_not_in_mismatch(test);
+ expect_not_in_wip(test);
+}
+
+static void resume_vf_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_resume_vf(test, false);
+}
+
+static void resume_vf_needs_retry_from(struct kunit *test)
+{
+ prepare_state_from_param(test);
+ try_resume_vf(test, true);
+}
+
+static void resume_vf_fails_on_send(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, paused, ARRAY_SIZE(paused));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_fail);
+
+ KUNIT_EXPECT_NE(test, 0, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_FAILED));
+
+ expect_not_resuming(test);
+ expect_not_in_mismatch(test);
+ expect_not_in_wip(test);
+}
+
+static void resume_vf_rejected_by_guc(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, paused, ARRAY_SIZE(paused));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_reject);
+
+ KUNIT_EXPECT_NE(test, 0, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_PAUSED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_MISMATCH));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_FAILED));
+
+ expect_not_resuming(test);
+ expect_not_in_wip(test);
+}
+
+static void resume_vf_canceled_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_FAILED));
+ expect_not_resuming(test);
+}
+
+static void resume_vf_refused_from(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+ int err;
+
+ prepare_state_from_param(test);
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_NE(test, 0, err = xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+ KUNIT_EXPECT_NE(test, err, -EIO);
+
+ KUNIT_EXPECT_TRUE(test, err == -EALREADY ||
+ pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_WIP));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_FAILED));
+}
+
+static void resume_vf_canceled_by_restart(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, paused, ARRAY_SIZE(paused));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_except_flr);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10, xe_gt_sriov_pf_control_restart, gt);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_WIP));
+}
+
+static void resume_vf_canceled_by_flr(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, paused, ARRAY_SIZE(paused));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_except_flr);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ xe_gt_sriov_pf_control_trigger_flr, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_WIP));
+}
+
+static void resume_vf_canceled_by_stop(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ prepare_state(test, VFUT1, paused, ARRAY_SIZE(paused));
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_busy_except_stop);
+
+ xe_kunit_helper_delayed_call(test, HZ / 10,
+ xe_gt_sriov_pf_control_stop_vf, gt, VFUT1);
+
+ KUNIT_EXPECT_EQ(test, -ECANCELED, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUMED));
+ KUNIT_EXPECT_TRUE(test, pf_expect_vf_not_state(gt, VFUT1, XE_GT_SRIOV_STATE_RESUME_WIP));
+}
+
+static void basic_pause_and_resume_vf(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_ASSERT_EQ(test, 0, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_resume_vf(gt, VFUT1));
+}
+
+static void basic_pause_and_stop_vf(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_ASSERT_EQ(test, 0, xe_gt_sriov_pf_control_pause_vf(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+}
+
+static void basic_stop_and_flr_vf(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_stop_vf(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+}
+
+static void basic_flr_and_flr_vf(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+}
+
+static void basic_flr_vfs(struct kunit *test)
+{
+ struct xe_gt *gt = test->priv;
+
+ XE_TEST_ACTIVATE_STUB(test, gt->sriov.pf.control.send_vf_control_cmd,
+ send_vf_control_cmd_pass_and_reply);
+
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT1));
+ KUNIT_EXPECT_EQ(test, 0, xe_gt_sriov_pf_control_trigger_flr(gt, VFUT2));
+}
+
+static struct kunit_case pf_control_test_cases[] = {
+ KUNIT_CASE(basic_pause_and_resume_vf),
+ KUNIT_CASE(basic_pause_and_stop_vf),
+ KUNIT_CASE(basic_stop_and_flr_vf),
+ KUNIT_CASE(basic_flr_and_flr_vf),
+ KUNIT_CASE(basic_flr_vfs),
+
+ KUNIT_CASE_PARAM(flr_vf_from, flr_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(flr_vf_needs_retry_from, flr_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(flr_vf_needs_retry_late_from, flr_must_pass_from_gen_params),
+ KUNIT_CASE(flr_vf_fails_on_send),
+ KUNIT_CASE(flr_vf_fails_on_reset),
+ KUNIT_CASE(flr_vf_rejected_by_guc),
+ KUNIT_CASE_SLOW(flr_vf_unconfirmed_by_guc),
+ KUNIT_CASE(flr_vf_confirmed_early_continue_by_guc),
+ KUNIT_CASE(flr_vf_confirmed_early_reject_by_guc),
+ KUNIT_CASE(flr_vf_confirmed_twice_by_guc),
+ KUNIT_CASE(flr_vf_confirmed_too_late_by_guc),
+ KUNIT_CASE(flr_vf_wrong_confirmation_from_guc),
+ KUNIT_CASE(flr_vf_unsolicited_confirmation_from_guc),
+ KUNIT_CASE(flr_vf_canceled_by_restart),
+
+ KUNIT_CASE_PARAM(stop_vf_from, stop_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(stop_vf_needs_retry_from, stop_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(stop_vf_refused_from, stop_must_fail_from_gen_params),
+ KUNIT_CASE_PARAM(stop_vf_canceled_from, stop_must_cancel_from_gen_params),
+ KUNIT_CASE(stop_vf_fails_on_send),
+ KUNIT_CASE(stop_vf_rejected_by_guc),
+ KUNIT_CASE(stop_vf_canceled_by_flr),
+ KUNIT_CASE(stop_vf_canceled_by_restart),
+
+ KUNIT_CASE_PARAM(pause_vf_from, pause_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(pause_vf_needs_retry_from, pause_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(pause_vf_refused_from, pause_must_fail_from_gen_params),
+ KUNIT_CASE_PARAM(pause_vf_canceled_from, pause_must_cancel_from_gen_params),
+ KUNIT_CASE(pause_vf_fails_on_send),
+ KUNIT_CASE(pause_vf_rejected_by_guc),
+ KUNIT_CASE_SLOW(pause_vf_unconfirmed_by_guc),
+ KUNIT_CASE(pause_vf_canceled_by_flr),
+ KUNIT_CASE(pause_vf_canceled_by_stop),
+ KUNIT_CASE(pause_vf_canceled_by_restart),
+
+ KUNIT_CASE_PARAM(resume_vf_from, resume_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(resume_vf_needs_retry_from, resume_must_pass_from_gen_params),
+ KUNIT_CASE_PARAM(resume_vf_refused_from, resume_must_fail_from_gen_params),
+ KUNIT_CASE_PARAM(resume_vf_canceled_from, resume_must_cancel_from_gen_params),
+ KUNIT_CASE(resume_vf_fails_on_send),
+ KUNIT_CASE(resume_vf_rejected_by_guc),
+ KUNIT_CASE(resume_vf_canceled_by_flr),
+ KUNIT_CASE(resume_vf_canceled_by_stop),
+ KUNIT_CASE(resume_vf_canceled_by_restart),
+
+ {}
+};
+
+static struct kunit_suite pf_control_suite = {
+ .name = "pf_control",
+ .test_cases = pf_control_test_cases,
+ .init = pf_control_test_init,
+};
+
+kunit_test_suite(pf_control_suite);
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
index e91c71d768ff..4863d79f72e0 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
@@ -4,6 +4,7 @@
*/
#include <drm/drm_managed.h>
+#include <kunit/static_stub.h>
#include "abi/guc_actions_sriov_abi.h"
@@ -196,6 +197,8 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit)
static unsigned long pf_get_default_timeout(enum xe_gt_sriov_control_bits bit)
{
+ KUNIT_STATIC_STUB_REDIRECT(pf_get_default_timeout, bit);
+
switch (bit) {
case XE_GT_SRIOV_STATE_FLR_WAIT_GUC:
case XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC:
@@ -1458,3 +1461,7 @@ void xe_gt_sriov_pf_control_restart(struct xe_gt *gt)
for (n = 1; n <= totalvfs; n++)
pf_enter_vf_ready(gt, n);
}
+
+#if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST)
+#include "tests/xe_gt_sriov_pf_control_kunit.c"
+#endif
--
2.43.0
next prev parent reply other threads:[~2024-08-09 17:23 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-09 16:51 [PATCH 00/12] PF: Improve VF control Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 01/12] drm/xe/pf: Add function to sanitize VF resources Michal Wajdeczko
2024-08-16 12:58 ` Piotr Piórkowski
2024-08-19 20:47 ` Lucas De Marchi
2024-08-20 9:38 ` Michal Wajdeczko
2024-08-20 13:16 ` Lucas De Marchi
2024-09-05 18:07 ` Rodrigo Vivi
2024-08-09 16:51 ` [PATCH 02/12] drm/xe/pf: Fix documentation formatting Michal Wajdeczko
2024-08-16 12:59 ` Piotr Piórkowski
2024-08-09 16:51 ` [PATCH 03/12] drm/xe/pf: Drop GuC notifications for non-existing VF Michal Wajdeczko
2024-08-16 13:01 ` Piotr Piórkowski
2024-08-19 17:51 ` Michal Wajdeczko
2024-08-22 10:48 ` Piotr Piórkowski
2024-08-09 16:51 ` [PATCH 04/12] drm/xe/pf: Improve VF control Michal Wajdeczko
2024-08-16 13:06 ` Piotr Piórkowski
2024-08-19 17:52 ` Michal Wajdeczko
2024-08-20 7:56 ` Piotr Piórkowski
2024-08-20 10:04 ` Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 05/12] drm/xe/tests: Allow deferred function call during KUnit test Michal Wajdeczko
2024-08-19 21:38 ` Lucas De Marchi
2024-08-20 10:23 ` Michal Wajdeczko
2024-08-20 13:21 ` Lucas De Marchi
2024-08-20 13:27 ` Lucas De Marchi
2024-08-09 16:51 ` [PATCH 06/12] drm/xe/tests: Add helper macro to detect if KUnit is running Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 07/12] drm/xe/tests: Add helpers to call stubs out of KUnit context Michal Wajdeczko
2024-08-19 21:52 ` Lucas De Marchi
2024-08-20 10:31 ` Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 08/12] drm/xe/guc: Define stub for xe_guc_ct_send_recv() Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 09/12] drm/xe/pf: Define stub for pf_sanitize_vf_resources() Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 10/12] drm/xe/pf: Define stub for pf_send_vf_control_cmd() Michal Wajdeczko
2024-08-09 16:51 ` [PATCH 11/12] drm/xe/tests: Add KUnit tests for VF control state machines Michal Wajdeczko
2024-08-09 17:23 ` Michal Wajdeczko [this message]
2024-08-22 10:51 ` [PATCH v2 " Piotr Piórkowski
2024-08-22 10:47 ` [PATCH " Piotr Piórkowski
2024-08-09 16:51 ` [PATCH 12/12] drm/xe/tests: Add KUnit tests for VF control GuC messages Michal Wajdeczko
2024-08-23 13:18 ` Piotr Piórkowski
2024-08-09 16:57 ` ✓ CI.Patch_applied: success for PF: Improve VF control Patchwork
2024-08-09 16:58 ` ✗ CI.checkpatch: warning " Patchwork
2024-08-09 16:58 ` ✗ CI.KUnit: failure " Patchwork
2024-08-09 17:28 ` ✓ CI.Patch_applied: success for PF: Improve VF control (rev2) Patchwork
2024-08-09 17:29 ` ✗ CI.checkpatch: warning " Patchwork
2024-08-09 17:30 ` ✓ CI.KUnit: success " Patchwork
2024-08-09 17:42 ` ✓ CI.Build: " Patchwork
2024-08-09 17:44 ` ✗ CI.Hooks: failure " Patchwork
2024-08-09 17:46 ` ✓ CI.checksparse: success " Patchwork
2024-08-09 18:06 ` ✓ CI.BAT: " Patchwork
2024-08-09 20:35 ` ✗ CI.FULL: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240809172315.749-1-michal.wajdeczko@intel.com \
--to=michal.wajdeczko@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=lucas.demarchi@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox