[PATCH 1/2] lib/xe: Add fault injection helper functions

Jonathan Cavitt jonathan.cavitt at intel.com
Thu Aug 21 21:17:43 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