From: Sobin Thomas <sobin.thomas@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: piotr.piorkowski@intel.com, kamil.konieczny@intel.com,
Sobin Thomas <sobin.thomas@intel.com>
Subject: [PATCH i-g-t 1/2] tests/intel/xe_debugfs: Add debugfs optional entry validation
Date: Tue, 16 Jun 2026 05:13:45 +0000 [thread overview]
Message-ID: <20260616051348.610849-2-sobin.thomas@intel.com> (raw)
In-Reply-To: <20260616051348.610849-1-sobin.thomas@intel.com>
Extend the root-dir subtest to validate additional optional Xe debugfs
entries. Optional entries are those that may not be present on all
platforms or configurations — their absence is not treated as a failure.
Validate:
- dgfx_pkg_residencies: Counter reads are non empty
- dgfx_pcie_link_residencies: PCIE LINK string content
- sriov_info: entry is non-empty
- workarounds: entry is non-empty
- atomic_svm_timeslice_ms: integer read/write
- poor_man_system_atomic_support: boolean read/write
- disable_late_binding: boolean read/write
v2: Fixed the optional file check and added fail count.
Replaced igt_debug with igt_info in few places (kamil)
v3: Removed uniused condition params and restored has_vram() usage.
Used igt_info() for validation failure logs.
Kept only new optional debugfs entries in this patch. (kamil)
Signed-off-by: Sobin Thomas <sobin.thomas@intel.com>
---
tests/intel/xe_debugfs.c | 177 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 173 insertions(+), 4 deletions(-)
diff --git a/tests/intel/xe_debugfs.c b/tests/intel/xe_debugfs.c
index 587e3e785..d7a204a09 100644
--- a/tests/intel/xe_debugfs.c
+++ b/tests/intel/xe_debugfs.c
@@ -39,11 +39,23 @@ IGT_TEST_DESCRIPTION("Validate Xe debugfs devnodes and their contents");
__m && ((__i) = __builtin_ctz(__m), 1); \
__m &= __m - 1)
+/* Validation types for debugfs read tests */
+enum debugfs_validate_type {
+ VALIDATE_NONE, /* Just check file exists */
+ VALIDATE_NON_EMPTY, /* Just check buffer is not empty */
+ VALIDATE_CONTAINS_STR, /* Check buffer contains expected string */
+ VALIDATE_INT_GE_ZERO, /* Parse as integer, verify >= 0 */
+ VALIDATE_BOOL, /* Check bool value (0 or 1) */
+};
+
struct check_entry {
const char *name_fmt;
int mode;
bool (*condition)(struct xe_device *xe_dev);
unsigned int (*iter_mask)(struct xe_device *xe_dev);
+ bool optional;
+ enum debugfs_validate_type validate;
+ const char *expected_str;
};
static unsigned int gt_iter_mask(struct xe_device *xe_dev)
@@ -131,6 +143,110 @@ static bool find_not_tested_files(int dir_fd, struct igt_list_head *hit_entries)
return found_not_tested;
}
+/* Validate that debugfs buffer is non-empty or contains expected string */
+static bool validate_string(int dirfd, const char *file_name, const char *expected_str)
+{
+ char buf[4096];
+ int ret = 0;
+
+ ret = igt_sysfs_read(dirfd, file_name, buf, sizeof(buf) - 1);
+ if (ret < 0)
+ return false;
+ buf[ret] = '\0';
+
+ /* Check for empty buffer */
+ if (strlen(buf) == 0) {
+ igt_warn("Empty output from %s\n", file_name);
+ return false;
+ }
+
+ /* If expecting specific string, verify it's present */
+ if (expected_str && !strstr(buf, expected_str)) {
+ igt_info("Expected '%s' not found in %s\n", expected_str, file_name);
+ return false;
+ }
+
+ if (expected_str)
+ igt_info("Successfully read %s: found '%s'\n", file_name, expected_str);
+ else
+ igt_info("Successfully read %s: %zd bytes\n%s\n", file_name, strlen(buf), buf);
+
+ return true;
+}
+
+static const char *mode_to_str(int mode)
+{
+ switch (mode & O_ACCMODE) {
+ case O_RDONLY: return "RO";
+ case O_WRONLY: return "WO";
+ case O_RDWR: return "RW";
+ default: return "UNKNOWN";
+ }
+}
+
+static bool validate_bool_file(int dirfd, const char *file_name, int mode)
+{
+ int orig_val = 0, read_val = 0, test_val = 0;
+
+ if (igt_sysfs_scanf(dirfd, file_name, "%d", &orig_val) != 1 ||
+ (orig_val != 0 && orig_val != 1))
+ return false;
+
+ if (mode == O_RDWR) {
+ test_val = (orig_val == 0) ? 1 : 0;
+
+ if (igt_sysfs_printf(dirfd, file_name, "%d", test_val) < 0)
+ return false;
+
+ if (igt_sysfs_scanf(dirfd, file_name, "%d", &read_val) != 1 || read_val != test_val)
+ return false;
+
+ /* Restore original value */
+ if (igt_sysfs_printf(dirfd, file_name, "%d", orig_val) < 0) {
+ igt_warn("Failed to restore original value for %s\n", file_name);
+ return false;
+ }
+ }
+
+ igt_info("Successfully validated %s bool %s\n", mode_to_str(mode), file_name);
+ return true;
+}
+
+static bool validate_int_file(int dirfd, const char *file_name, int mode)
+{
+ int orig_val = 0, new_val = 0, read_val = 0;
+
+ if (igt_sysfs_scanf(dirfd, file_name, "%d", &orig_val) != 1)
+ return false;
+
+ if (orig_val < 0)
+ return false;
+
+ if (mode == O_RDWR) {
+ new_val = orig_val + 1;
+ if (new_val < 0)
+ new_val = orig_val - 1;
+ if (igt_sysfs_printf(dirfd, file_name, "%d", new_val) < 0)
+ return false;
+ if (igt_sysfs_scanf(dirfd, file_name, "%d", &read_val) != 1)
+ return false;
+ if (read_val != new_val)
+ return false;
+ /* Restore original value */
+ if (igt_sysfs_printf(dirfd, file_name, "%d", orig_val) < 0) {
+ igt_warn("Failed to restore original value for %s\n", file_name);
+ return false;
+ }
+
+ igt_info("Successfully validated writing int %s: %d\n",
+ file_name, new_val);
+ } else {
+ igt_info("Successfully validated reading int %s: %d\n",
+ file_name, orig_val);
+ }
+ return true;
+}
+
static bool file_in_dir_exists(int dirfd, const char *file_name, int mode)
{
int fd = openat(dirfd, file_name, mode);
@@ -139,10 +255,39 @@ static bool file_in_dir_exists(int dirfd, const char *file_name, int mode)
close(fd);
return true;
}
-
return false;
}
+static bool validate_debugfs_file(int dirfd, const char *file_name, int mode,
+ enum debugfs_validate_type validate, const char *expected_str)
+{
+ bool result = true;
+
+ if (validate == VALIDATE_NONE)
+ return true;
+
+ switch (validate) {
+ case VALIDATE_NON_EMPTY:
+ result = validate_string(dirfd, file_name, NULL);
+ break;
+ case VALIDATE_CONTAINS_STR:
+ result = validate_string(dirfd, file_name, expected_str);
+ break;
+ case VALIDATE_INT_GE_ZERO:
+ result = validate_int_file(dirfd, file_name, mode);
+ break;
+ case VALIDATE_BOOL:
+ result = validate_bool_file(dirfd, file_name, mode);
+ break;
+ default:
+ igt_warn("Unknown validate type %d for %s\n", validate, file_name);
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
/*
* Return: negative error code on failure, or number of missing files
*/
@@ -151,6 +296,7 @@ static int debugfs_validate_entries(struct xe_device *xe_dev, int dir_fd,
{
struct igt_list_head hit_entries;
int missing_count = 0;
+ int fail_count = 0;
int err = 0;
IGT_INIT_LIST_HEAD(&hit_entries);
@@ -210,9 +356,22 @@ static int debugfs_validate_entries(struct xe_device *xe_dev, int dir_fd,
}
if (!file_in_dir_exists(dir_fd, entry->name, check->mode)) {
- igt_warn("Missing debugfs file: %s\n", entry->name);
- missing_count++;
+ if (check->optional) {
+ igt_info("Optional entry %s not found (skipped)\n",
+ entry->name);
+ } else {
+ igt_info("Missing debugfs file: %s\n",
+ entry->name);
+ missing_count++;
+ }
+ } else {
+ if (!validate_debugfs_file(dir_fd, entry->name, check->mode,
+ check->validate, check->expected_str)) {
+ igt_info("Fail at debugfs file: %s\n", entry->name);
+ fail_count++;
+ }
}
+
}
}
@@ -229,7 +388,10 @@ out:
}
}
- return (err < 0) ? err : missing_count;
+ if (fail_count || missing_count)
+ igt_warn("Fails: %d missing debugfs file(s): %d\n", fail_count, missing_count);
+
+ return (err < 0) ? err : (missing_count + fail_count);
}
/**
@@ -240,6 +402,7 @@ static void test_root_dir(struct xe_device *xe_dev)
{
const struct check_entry expected_files[] = {
{ "clients", O_RDONLY },
+ { "disable_late_binding", O_RDWR, .optional = true, .validate = VALIDATE_BOOL },
{ "forcewake_all", O_WRONLY },
{ "gem_names", O_RDONLY },
{ "gt%u", O_RDONLY, NULL, gt_iter_mask }, /* gt0, gt1, ... */
@@ -247,6 +410,12 @@ static void test_root_dir(struct xe_device *xe_dev)
{ "info", O_RDONLY },
{ "name", O_RDONLY },
{ "tile%u", O_RDONLY, NULL, tile_iter_mask }, /* tile0, tile1, ... */
+ { "poor_man_system_atomic_support", O_RDWR, .optional = true, .validate = VALIDATE_BOOL },
+ { "dgfx_pkg_residencies", O_RDONLY, .optional = true, .validate = VALIDATE_NON_EMPTY },
+ { "dgfx_pcie_link_residencies", O_RDONLY, .optional = true, .validate = VALIDATE_CONTAINS_STR, .expected_str = "PCIE LINK" },
+ { "sriov_info", O_RDONLY, .optional = true, .validate = VALIDATE_NON_EMPTY },
+ { "workarounds", O_RDONLY, .optional = true, .validate = VALIDATE_NON_EMPTY },
+ { "atomic_svm_timeslice_ms", O_RDWR, .optional = true, .validate = VALIDATE_INT_GE_ZERO },
};
int debugfs_fd = igt_debugfs_dir(xe_dev->fd);
int missing_count;
--
2.52.0
next prev parent reply other threads:[~2026-06-16 5:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 5:13 [PATCH i-g-t 0/2] tests/intel/xe_debugfs: Add debugfs entry Sobin Thomas
2026-06-16 5:13 ` Sobin Thomas [this message]
2026-06-16 5:13 ` [PATCH i-g-t 2/2] tests/intel/xe_debugfs: Add checks for existing root dir entries Sobin Thomas
2026-06-16 6:40 ` ✓ Xe.CI.BAT: success for tests/intel/xe_debugfs: Add debugfs entry Patchwork
2026-06-16 6:46 ` ✓ i915.CI.BAT: " Patchwork
2026-06-16 8:28 ` ✓ Xe.CI.FULL: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260616051348.610849-2-sobin.thomas@intel.com \
--to=sobin.thomas@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=kamil.konieczny@intel.com \
--cc=piotr.piorkowski@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.