Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
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


  reply	other threads:[~2026-06-16  5:15 UTC|newest]

Thread overview: 5+ 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox