Re: [PATCH i-g-t v1] tests/intel/xe_ras: Add test for GPU health indicator
"Anirban, Sk" <[email protected]>
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
Hi Soham, On 10-08-2026 11:35 pm, Soham Purkait wrote: > 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" Above two are unused includes. Remove them. > + > +/** > + * 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); Check if we can use free() in exit handler as this can be called even if any fata signal is being invoked. > + 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); Imo it's better to call the exit handler in IGT fixture or under igt_subtest("gpu-health") section. > + > + /** > + * Invalid writes must be rejected with EINVAL. > + */ > + errno = 0; We are not using errno anywhere else, check for dead codes. > + 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. > + */ I think these type of comment format only required in case of Test/Subtest descriptions. Cross verify once if we can use here. Thanks, Anirban > + 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',