[PATCH i-g-t 1/2] lib/xe: Add fault injection helper functions
Jonathan Cavitt
jonathan.cavitt at intel.com
Thu Aug 21 22:24:37 UTC 2025
Move several functions from the xe_fault_injection test suite to their
own helper function. Specifically, the following functions were
migrated over:
- fail_function_injection_enabled
- injection_list_add
- injection_list_append
- injection_list_remove
- injection_list_clear
- setup_injection_fault
- get_remaining_injection_count
- set_retval
Several functions were renamed during the migration process to unify the
namespace. Additionally, a new function, injection_exit_handler, was
added, which performs the same functionality that the function call
'igt_install_exit_handler(cleanup_injection_fault);' performed before.
The declaration for struct fault_injection_params was also moved over,
as well as a default param setup.
Suggested-by: John Harrison <john.c.harrison at intel.com>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt at intel.com>
---
lib/meson.build | 1 +
lib/xe/xe_fault_injection.c | 157 +++++++++++++++++++++++++
lib/xe/xe_fault_injection.h | 51 ++++++++
tests/intel/xe_fault_injection.c | 195 ++-----------------------------
4 files changed, 220 insertions(+), 184 deletions(-)
create mode 100644 lib/xe/xe_fault_injection.c
create mode 100644 lib/xe/xe_fault_injection.h
diff --git a/lib/meson.build b/lib/meson.build
index f078dad4e5..21bc977e94 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -116,6 +116,7 @@ lib_sources = [
'igt_msm.c',
'igt_dsc.c',
'igt_hook.c',
+ 'xe/xe_fault_injection.c',
'xe/xe_gt.c',
'xe/xe_ioctl.c',
'xe/xe_legacy.c',
diff --git a/lib/xe/xe_fault_injection.c b/lib/xe/xe_fault_injection.c
new file mode 100644
index 0000000000..2693300fc2
--- /dev/null
+++ b/lib/xe/xe_fault_injection.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#include "igt.h"
+#include "igt_sysfs.h"
+#include "xe/xe_fault_injection.h"
+#include "xe/xe_ioctl.h"
+
+static int fail_function_open(void)
+{
+ int debugfs_fail_function_dir_fd;
+ const char *debugfs_root;
+ char path[96];
+
+ debugfs_root = igt_debugfs_mount();
+ igt_assert(debugfs_root);
+
+ sprintf(path, "%s/fail_function", debugfs_root);
+
+ if (access(path, F_OK))
+ return -1;
+
+ debugfs_fail_function_dir_fd = open(path, O_RDONLY);
+ igt_debug_on_f(debugfs_fail_function_dir_fd < 0, "path: %s\n", path);
+
+ return debugfs_fail_function_dir_fd;
+}
+
+/*
+ * The injectable file requires CONFIG_FUNCTION_ERROR_INJECTION in kernel.
+ */
+bool fail_function_injection_enabled(void)
+{
+ char *contents;
+ int dir;
+
+ dir = fail_function_open();
+ if (dir < 0)
+ return false;
+
+ contents = igt_sysfs_get(dir, "injectable");
+ if (contents == NULL)
+ return false;
+
+ free(contents);
+
+ return true;
+}
+
+void injection_list_add(const char function_name[])
+{
+ int dir;
+
+ dir = fail_function_open();
+
+ igt_assert_lte(0, dir);
+ igt_assert_lte(0, igt_sysfs_printf(dir, "inject", "%s", function_name));
+
+ close(dir);
+}
+
+void injection_list_append(const char function_name[])
+{
+ int dir, fd, ret;
+
+ dir = fail_function_open();
+ igt_assert_lte(0, dir);
+
+ fd = openat(dir, "inject", O_WRONLY | O_APPEND);
+ igt_assert_lte(0, fd);
+ ret = write(fd, function_name, strlen(function_name));
+ igt_assert_lte(0, ret);
+
+ close(fd);
+ close(dir);
+}
+
+void injection_list_remove(const char function_name[])
+{
+ int dir;
+
+ dir = fail_function_open();
+
+ igt_assert_lte(0, dir);
+ igt_assert_lte(0, igt_sysfs_printf(dir, "inject", "!%s", function_name));
+
+ close(dir);
+}
+
+void injection_list_clear(void)
+{
+ /* If nothing specified (‘’) injection list is cleared */
+ return injection_list_add("");
+}
+
+
+
+/*
+ * See https://docs.kernel.org/fault-injection/fault-injection.html#application-examples
+ */
+void injection_setup_fault(const struct fault_injection_params *fault_params)
+{
+ int dir;
+
+ if (!fault_params)
+ fault_params = &default_fault_params;
+
+ igt_assert(fault_params->probability >= 0);
+ igt_assert(fault_params->probability <= 100);
+
+
+ dir = fail_function_open();
+ igt_assert_lte(0, dir);
+
+ igt_debug("probability = %d, interval = %d, times = %d, space = %u\n",
+ fault_params->probability, fault_params->interval,
+ fault_params->times, fault_params->space);
+
+ igt_assert_lte(0, igt_sysfs_printf(dir, "task-filter", "N"));
+ igt_sysfs_set_u32(dir, "probability", fault_params->probability);
+ igt_sysfs_set_u32(dir, "interval", fault_params->interval);
+ igt_sysfs_set_s32(dir, "times", fault_params->times);
+ igt_sysfs_set_u32(dir, "space", fault_params->space);
+ igt_sysfs_set_u32(dir, "verbose", 1);
+
+ close(dir);
+}
+
+int injection_get_remaining_count(void)
+{
+ int dir, val;
+
+ dir = fail_function_open();
+ igt_assert_lte(0, dir);
+
+ val = igt_sysfs_get_s32(dir, "times");
+
+ close(dir);
+ return val;
+}
+
+void injection_set_retval(const char function_name[], long long retval)
+{
+ char path[96];
+ int dir;
+
+ dir = fail_function_open();
+ igt_assert_lte(0, dir);
+
+ sprintf(path, "%s/retval", function_name);
+ igt_assert_lte(0, igt_sysfs_printf(dir, path, "%#016llx", retval));
+
+ close(dir);
+}
+
diff --git a/lib/xe/xe_fault_injection.h b/lib/xe/xe_fault_injection.h
new file mode 100644
index 0000000000..5a42d9ad36
--- /dev/null
+++ b/lib/xe/xe_fault_injection.h
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+struct fault_injection_params {
+ /* @probability: Likelihood of failure injection, in percent. */
+ uint32_t probability;
+ /* @interval: Specifies the interval between failures */
+ uint32_t interval;
+ /* @times: Specifies how many times failures may happen at most */
+ int32_t times;
+ /*
+ * @space: Specifies how many times fault injection is suppressed before
+ * first injection
+ */
+ uint32_t space;
+};
+
+/*
+ * Default fault injection parameters which injects fault on first call to the
+ * configured fail_function.
+ */
+static const struct fault_injection_params default_fault_params = {
+ .probability = 100,
+ .interval = 0,
+ .times = -1,
+ .space = 0
+};
+
+bool fail_function_injection_enabled(void);
+
+void injection_list_add(const char function_name[]);
+void injection_list_append(const char function_name[]);
+void injection_list_remove(const char function_name[]);
+void injection_list_clear(void);
+
+void injection_setup_fault(const struct fault_injection_params *fault_params);
+
+int injection_get_remaining_count(void);
+void injection_set_retval(const char function_name[], long long retval);
+
+static void cleanup_injection_fault(int sig)
+{
+ injection_list_clear();
+}
+
+static inline void injection_exit_handler(void)
+{
+ igt_install_exit_handler(cleanup_injection_fault);
+}
diff --git a/tests/intel/xe_fault_injection.c b/tests/intel/xe_fault_injection.c
index 04de2bfd54..ca4447565f 100644
--- a/tests/intel/xe_fault_injection.c
+++ b/tests/intel/xe_fault_injection.c
@@ -20,6 +20,7 @@
#include "igt_sysfs.h"
#include "lib/igt_syncobj.h"
#include "lib/intel_pat.h"
+#include "xe/xe_fault_injection.h"
#include "xe/xe_ioctl.h"
#include "xe/xe_oa.h"
#include "xe/xe_query.h"
@@ -31,39 +32,6 @@
#define MAX_INJECTIONS_PER_ITER 100
int32_t inject_iters_raw;
-struct fault_injection_params {
- /* @probability: Likelihood of failure injection, in percent. */
- uint32_t probability;
- /* @interval: Specifies the interval between failures */
- uint32_t interval;
- /* @times: Specifies how many times failures may happen at most */
- int32_t times;
- /*
- * @space: Specifies how many times fault injection is suppressed before
- * first injection
- */
- uint32_t space;
-};
-
-static int fail_function_open(void)
-{
- int debugfs_fail_function_dir_fd;
- const char *debugfs_root;
- char path[96];
-
- debugfs_root = igt_debugfs_mount();
- igt_assert(debugfs_root);
-
- sprintf(path, "%s/fail_function", debugfs_root);
-
- if (access(path, F_OK))
- return -1;
-
- debugfs_fail_function_dir_fd = open(path, O_RDONLY);
- igt_debug_on_f(debugfs_fail_function_dir_fd < 0, "path: %s\n", path);
-
- return debugfs_fail_function_dir_fd;
-}
static void ignore_dmesg_errors_from_dut(const char pci_slot[])
{
@@ -81,153 +49,12 @@ static void ignore_dmesg_errors_from_dut(const char pci_slot[])
igt_emit_ignore_dmesg_regex(regex);
}
-/*
- * The injectable file requires CONFIG_FUNCTION_ERROR_INJECTION in kernel.
- */
-static bool fail_function_injection_enabled(void)
-{
- char *contents;
- int dir;
-
- dir = fail_function_open();
- if (dir < 0)
- return false;
-
- contents = igt_sysfs_get(dir, "injectable");
- if (contents == NULL)
- return false;
-
- free(contents);
-
- return true;
-}
-
-static void injection_list_add(const char function_name[])
-{
- int dir;
-
- dir = fail_function_open();
-
- igt_assert_lte(0, dir);
- igt_assert_lte(0, igt_sysfs_printf(dir, "inject", "%s", function_name));
-
- close(dir);
-}
-
-static void injection_list_append(const char function_name[])
-{
- int dir, fd, ret;
-
- dir = fail_function_open();
- igt_assert_lte(0, dir);
-
- fd = openat(dir, "inject", O_WRONLY | O_APPEND);
- igt_assert_lte(0, fd);
- ret = write(fd, function_name, strlen(function_name));
- igt_assert_lte(0, ret);
-
- close(fd);
- close(dir);
-}
-
-static void injection_list_remove(const char function_name[])
-{
- int dir;
-
- dir = fail_function_open();
-
- igt_assert_lte(0, dir);
- igt_assert_lte(0, igt_sysfs_printf(dir, "inject", "!%s", function_name));
-
- close(dir);
-}
-
-static void injection_list_clear(void)
-{
- /* If nothing specified (‘’) injection list is cleared */
- return injection_list_add("");
-}
-
-/*
- * Default fault injection parameters which injects fault on first call to the
- * configured fail_function.
- */
-static const struct fault_injection_params default_fault_params = {
- .probability = 100,
- .interval = 0,
- .times = -1,
- .space = 0
-};
-
-/*
- * See https://docs.kernel.org/fault-injection/fault-injection.html#application-examples
- */
-static void setup_injection_fault(const struct fault_injection_params *fault_params)
-{
- int dir;
-
- if (!fault_params)
- fault_params = &default_fault_params;
-
- igt_assert(fault_params->probability >= 0);
- igt_assert(fault_params->probability <= 100);
-
-
- dir = fail_function_open();
- igt_assert_lte(0, dir);
-
- igt_debug("probability = %d, interval = %d, times = %d, space = %u\n",
- fault_params->probability, fault_params->interval,
- fault_params->times, fault_params->space);
-
- igt_assert_lte(0, igt_sysfs_printf(dir, "task-filter", "N"));
- igt_sysfs_set_u32(dir, "probability", fault_params->probability);
- igt_sysfs_set_u32(dir, "interval", fault_params->interval);
- igt_sysfs_set_s32(dir, "times", fault_params->times);
- igt_sysfs_set_u32(dir, "space", fault_params->space);
- igt_sysfs_set_u32(dir, "verbose", 1);
-
- close(dir);
-}
-
-static void cleanup_injection_fault(int sig)
-{
- injection_list_clear();
-}
-
-static int get_remaining_injection_count(void)
-{
- int dir, val;
-
- dir = fail_function_open();
- igt_assert_lte(0, dir);
-
- val = igt_sysfs_get_s32(dir, "times");
-
- close(dir);
- return val;
-}
-
-static void set_retval(const char function_name[], long long retval)
-{
- char path[96];
- int dir;
-
- dir = fail_function_open();
- igt_assert_lte(0, dir);
-
- sprintf(path, "%s/retval", function_name);
- igt_assert_lte(0, igt_sysfs_printf(dir, path, "%#016llx", retval));
-
- close(dir);
-}
-
static void ignore_fail_dump_in_dmesg(const char function_name[], bool enable)
{
if (strstr(function_name, "send_recv")) {
if (enable) {
injection_list_append("xe_is_injection_active");
- set_retval("xe_is_injection_active", INJECT_ERRNO);
+ injection_set_retval("xe_is_injection_active", INJECT_ERRNO);
} else {
injection_list_remove("xe_is_injection_active");
}
@@ -268,7 +95,7 @@ inject_fault_probe(int fd, const char pci_slot[], const char function_name[])
ignore_dmesg_errors_from_dut(pci_slot);
injection_list_add(function_name);
- set_retval(function_name, INJECT_ERRNO);
+ injection_set_retval(function_name, INJECT_ERRNO);
ignore_fail_dump_in_dmesg(function_name, true);
igt_kmod_bind("xe", pci_slot);
@@ -307,7 +134,7 @@ static void probe_fail_guc(int fd, const char pci_slot[], const char function_na
for (int i = iter_start; i < iter_end; i++) {
fault_params->space = i;
fault_params->times = MAX_INJECTIONS_PER_ITER;
- setup_injection_fault(fault_params);
+ injection_setup_fault(fault_params);
inject_fault_probe(fd, pci_slot, function_name);
igt_kmod_unbind("xe", pci_slot);
@@ -315,7 +142,7 @@ static void probe_fail_guc(int fd, const char pci_slot[], const char function_na
* if no injection occurred we've tested all the injection
* points for this function and can therefore stop iterating.
*/
- if (get_remaining_injection_count() == MAX_INJECTIONS_PER_ITER)
+ if (injection_get_remaining_count() == MAX_INJECTIONS_PER_ITER)
break;
}
@@ -353,7 +180,7 @@ exec_queue_create_fail(int fd, struct drm_xe_engine_class_instance *instance,
ignore_dmesg_errors_from_dut(pci_slot);
injection_list_add(function_name);
- set_retval(function_name, INJECT_ERRNO);
+ injection_set_retval(function_name, INJECT_ERRNO);
igt_assert(__xe_exec_queue_create(fd, vm, 1, 1, instance, 0, &exec_queue_id) != 0);
injection_list_remove(function_name);
@@ -389,7 +216,7 @@ vm_create_fail(int fd, const char pci_slot[],
ignore_dmesg_errors_from_dut(pci_slot);
injection_list_add(function_name);
- set_retval(function_name, INJECT_ERRNO);
+ injection_set_retval(function_name, INJECT_ERRNO);
igt_assert(simple_vm_create(fd, flags) != 0);
injection_list_remove(function_name);
@@ -452,7 +279,7 @@ vm_bind_fail(int fd, const char pci_slot[], const char function_name[])
ignore_dmesg_errors_from_dut(pci_slot);
injection_list_add(function_name);
- set_retval(function_name, INJECT_ERRNO);
+ injection_set_retval(function_name, INJECT_ERRNO);
igt_assert(simple_vm_bind(fd, vm) != 0);
injection_list_remove(function_name);
@@ -501,7 +328,7 @@ oa_add_config_fail(int fd, int sysfs, int devid,
ignore_dmesg_errors_from_dut(pci_slot);
injection_list_add(function_name);
- set_retval(function_name, INJECT_ERRNO);
+ injection_set_retval(function_name, INJECT_ERRNO);
igt_assert_lt(intel_xe_perf_ioctl(fd, DRM_XE_OBSERVATION_OP_ADD_CONFIG, &config), 0);
injection_list_remove(function_name);
@@ -611,8 +438,8 @@ igt_main_args("I:", NULL, help_str, opt_handler, NULL)
devid = intel_get_drm_devid(fd);
sysfs = igt_sysfs_open(fd);
igt_device_get_pci_slot_name(fd, pci_slot);
- setup_injection_fault(&default_fault_params);
- igt_install_exit_handler(cleanup_injection_fault);
+ injection_setup_fault(&default_fault_params);
+ injection_exit_handler();
is_vf_device = intel_is_vf_device(fd);
}
--
2.43.0
More information about the Intel-gfx-trybot
mailing list