[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