[PATCH i-g-t v1] tests/intel/xe_ras: Add test for GPU health indicator

Soham Purkait <[email protected]>
Newsgroups org.freedesktop.lists.igt-dev
Message-ID <[email protected]>
Add a new Xe RAS test exercising the gpu_health sysfs attribute
exposed by the Xe driver on platforms that provide the system
controller. The attribute reports and allows updating the GPU
health state.

The gpu-health subtest validates each valid state by writing it
and reading the value back, and checks that invalid writes are
rejected with -EINVAL, guarding against regressions in the
implementation.

v1:
 - Platform-conditional skip w/o fd leak. (Anirban)
 - Restore via exit handler. (Anirban)

Signed-off-by: Soham Purkait <[email protected]>
---
 tests/intel/xe_ras.c | 135 +++++++++++++++++++++++++++++++++++++++++++
 tests/meson.build    |   1 +
 2 files changed, 136 insertions(+)
 create mode 100644 tests/intel/xe_ras.c

diff --git a/tests/intel/xe_ras.c b/tests/intel/xe_ras.c
new file mode 100644
index 000000000..c43dc3bdd
--- /dev/null
+++ b/tests/intel/xe_ras.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "igt.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_query.h"
+
+/**
+ * TEST: Test Xe RAS (Reliability, Availability, Serviceability) functionality
+ * Category: Core
+ * Mega feature: RAS
+ * Sub-category: RAS tests
+ * Functionality: ras
+ * Test category: Functional tests
+ *
+ * SUBTEST: gpu-health
+ * Description: Verify the gpu_health sysfs attribute accepts each valid
+ *		state (ok/warning/critical) and rejects invalid writes
+ *		with EINVAL.
+ */
+
+IGT_TEST_DESCRIPTION("Tests for Xe RAS");
+
+#define GPU_HEALTH_ATTR	"device/gpu_health"
+
+static const char * const gpu_health_states[] = {
+	"ok",
+	"warning",
+	"critical",
+};
+
+static struct {
+	int sys_fd;
+	char *orig_health;
+} gpu_health_ctx = { .sys_fd = -1 };
+
+static void restore_gpu_health(int sig)
+{
+	if (gpu_health_ctx.sys_fd < 0 || !gpu_health_ctx.orig_health)
+		return;
+
+	igt_sysfs_set(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR, gpu_health_ctx.orig_health);
+	free(gpu_health_ctx.orig_health);
+	gpu_health_ctx.orig_health = NULL;
+	close(gpu_health_ctx.sys_fd);
+	gpu_health_ctx.sys_fd = -1;
+}
+
+static bool valid_gpu_health(const char *s)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gpu_health_states); i++)
+		if (!strcmp(s, gpu_health_states[i]))
+			return true;
+
+	return false;
+}
+
+static void test_gpu_health(int xe)
+{
+	char *health = NULL;
+	int ret;
+	int i;
+
+	gpu_health_ctx.sys_fd = igt_sysfs_open(xe);
+	igt_assert(gpu_health_ctx.sys_fd >= 0);
+
+	if (!igt_sysfs_has_attr(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR)) {
+		close(gpu_health_ctx.sys_fd);
+		gpu_health_ctx.sys_fd = -1;
+		igt_skip("gpu_health sysfs attribute not exposed by driver\n");
+	}
+
+	gpu_health_ctx.orig_health = igt_sysfs_get(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR);
+	igt_assert_f(gpu_health_ctx.orig_health, "Failed to read %s\n", GPU_HEALTH_ATTR);
+	igt_debug("initial gpu_health: %s\n", gpu_health_ctx.orig_health);
+	igt_assert_f(valid_gpu_health(gpu_health_ctx.orig_health),
+		     "Unexpected initial gpu_health value: '%s'\n",
+		     gpu_health_ctx.orig_health);
+
+	igt_install_exit_handler(restore_gpu_health);
+
+	/**
+	 * Invalid writes must be rejected with EINVAL.
+	 */
+	errno = 0;
+	ret = igt_sysfs_write(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR, "bogus", strlen("bogus"));
+	igt_assert_f(ret == -EINVAL,
+		     "Write of invalid value to %s returned %d, expected -EINVAL\n",
+		     GPU_HEALTH_ATTR, ret);
+
+	/**
+	 * Write each valid state and read it back to confirm the driver
+	 * accepts and reflects the requested value.
+	 */
+	for (i = 0; i < ARRAY_SIZE(gpu_health_states); i++) {
+		const char *state = gpu_health_states[i];
+
+		igt_assert_f(igt_sysfs_set(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR, state),
+			     "Failed to write '%s' to %s\n",
+			     state, GPU_HEALTH_ATTR);
+
+		health = igt_sysfs_get(gpu_health_ctx.sys_fd, GPU_HEALTH_ATTR);
+		igt_assert(health);
+		igt_assert_f(!strcmp(health, state),
+			     "gpu_health readback mismatch: wrote '%s', read '%s'\n",
+			     state, health);
+		free(health);
+	}
+
+	restore_gpu_health(0);
+}
+
+int igt_main()
+{
+	int xe;
+
+	igt_fixture()
+		xe = drm_open_driver(DRIVER_XE);
+
+	igt_subtest("gpu-health")
+		test_gpu_health(xe);
+
+	igt_fixture()
+		drm_close_driver(xe);
+}
diff --git a/tests/meson.build b/tests/meson.build
index 6d90627b9..4ab4ef603 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -333,6 +333,7 @@ intel_xe_progs = [
 	'xe_prime_self_import',
 	'xe_pxp',
 	'xe_query',
+	'xe_ras',
 	'xe_render_copy',
 	'xe_vm',
 	'xe_userptr_pressure',
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.