[PATCH] tests/intel/xe_debugfs: add GT-level debugfs coverage
Smitha Balasubramanyam <[email protected]> Tue, 28 Jul 2026 11:47:30 +0530
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
Extend xe_debugfs with subtests exercising the GT-level debugfs attributes exposed by the Xe driver. Subtests: - gt-dir: presence and content check for unconditional GT attrs - gt-default-lrc: reads per-engine-class default LRC attrs; skips engine classes absent on the GT, fails if none are found - gt-dir-pf-only: presence and content check for PF-only attrs; skipped entirely on VF - gt-stats-write: writes an invalid key to stats and verifies the kernel rejects it with an error; confirms stats remains readable after the rejected write Signed-off-by: Smitha Balasubramanyam <[email protected]> --- tests/intel/xe_debugfs.c | 150 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 3 deletions(-) diff --git a/tests/intel/xe_debugfs.c b/tests/intel/xe_debugfs.c index da482157e..74c9d7b0b 100644 --- a/tests/intel/xe_debugfs.c +++ b/tests/intel/xe_debugfs.c @@ -9,6 +9,7 @@ #include "igt.h" #include "igt_debugfs.h" #include "igt_dir.h" +#include "igt_sriov_device.h" #include "igt_sysfs.h" #include "xe/xe_query.h" @@ -16,6 +17,8 @@ struct { bool warn_on_not_hit; } opt = { 0 }; +static int *gt_dirs; + /** * TEST: Xe debugfs test * Description: Xe-specific debugfs tests. These are complementary to the @@ -30,6 +33,20 @@ struct { * * SUBTEST: check-gt-reg-sr * Description: Check the reg_sr list associated with GTs for missing reg values + * + * SUBTEST: gt-dir + * Description: Check GT debugfs attrs present on all contexts for each GT. + * + * SUBTEST: gt-default-lrc + * Description: Validate default LRC content for each engine class present on + * each GT. Engine classes absent on the GT are skipped. + * + * SUBTEST: gt-dir-pf-only + * Description: Check that PF-only GT debugfs attrs are present for each GT on PF. + * + * SUBTEST: gt-stats-write + * Description: Write an invalid payload to the stats debugfs attribute for + * each GT to verify the kernel rejects malformed input with an error. */ IGT_TEST_DESCRIPTION("Validate Xe debugfs devnodes and their contents"); @@ -166,10 +183,12 @@ static bool validate_string(int dirfd, const char *file_name, const char *expect return false; } - if (expected_str) + 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); + } else { + igt_info("Successfully read %s: %zd bytes\n", file_name, strlen(buf)); + igt_debug("%s\n", buf); + } return true; } @@ -595,6 +614,84 @@ static void check_gt_reg_sr(int fd, int gt) igt_assert_eq(problems, 0); } +static void test_gt_dir(struct xe_device *xe_dev, int gt) +{ + const struct check_entry expected_files[] = { + { "register-save-restore", O_RDONLY, .validate = VALIDATE_NON_EMPTY }, + { "hwconfig", O_RDONLY, .validate = VALIDATE_NON_EMPTY }, + { "stats", O_RDONLY, .validate = VALIDATE_NON_EMPTY }, + { "force_reset", O_WRONLY }, + { "force_reset_sync", O_WRONLY }, + }; + int missing_count = debugfs_validate_entries(xe_dev, gt_dirs[gt], expected_files, + ARRAY_SIZE(expected_files)); + + igt_fail_on_f(missing_count > 0, + "GT%d: %d GT debugfs attrs missing (see warnings above)\n", + gt, missing_count); +} + +static void test_gt_default_lrc(int gt) +{ + static const char * const lrc_attrs[] = { + "default_lrc_rcs", + "default_lrc_ccs", + "default_lrc_bcs", + "default_lrc_vcs", + "default_lrc_vecs", + }; + int engines_present = 0; + + for (size_t i = 0; i < ARRAY_SIZE(lrc_attrs); i++) { + if (!file_in_dir_exists(gt_dirs[gt], lrc_attrs[i], O_RDONLY)) { + igt_info("GT%d: %s absent\n", gt, lrc_attrs[i]); + continue; + } + + engines_present++; + igt_assert_f(validate_debugfs_file(gt_dirs[gt], lrc_attrs[i], + O_RDONLY, VALIDATE_NON_EMPTY, NULL), + "GT%d: %s is empty or unreadable\n", gt, lrc_attrs[i]); + } + + igt_assert_f(engines_present > 0, + "GT%d: no default_lrc_* attrs found; expected at least one engine\n", + gt); +} + +static void test_gt_dir_pf_only(struct xe_device *xe_dev, int gt) +{ + const struct check_entry expected_files[] = { + { "hw_engines", O_RDONLY, .validate = VALIDATE_NON_EMPTY }, + { "steering", O_RDONLY, .validate = VALIDATE_NON_EMPTY }, + }; + int missing_count = debugfs_validate_entries(xe_dev, gt_dirs[gt], expected_files, + ARRAY_SIZE(expected_files)); + + igt_fail_on_f(missing_count > 0, + "GT%d: %d PF-only GT debugfs attrs missing (see warnings above)\n", + gt, missing_count); +} + +static void test_gt_stats_write(int gt) +{ + char buf[4096]; + int len, wret; + + len = igt_sysfs_read(gt_dirs[gt], "stats", buf, sizeof(buf) - 1); + igt_assert_f(len > 0, + "GT%d: pre-write stats read failed or empty (%d)\n", gt, len); + + wret = igt_sysfs_write(gt_dirs[gt], "stats", "invalid_key 0\n", strlen("invalid_key 0\n")); + igt_assert_f(wret < 0, + "GT%d: stats write accepted invalid key (returned %d, expected error)\n", + gt, wret); + + len = igt_sysfs_read(gt_dirs[gt], "stats", buf, sizeof(buf) - 1); + igt_assert_f(len > 0, + "GT%d: stats still readable after rejected write (%d)\n", gt, len); +} + const char *help_str = " --warn-not-hit|--w\tWarn about devfs nodes that have no tests"; @@ -620,13 +717,28 @@ int igt_main_args("", long_options, help_str, opt_handler, NULL) { struct xe_device *xe_dev; unsigned int t; + bool is_vf = false; int fd = -1, gt; + int max_gt; igt_fixture() { fd = drm_open_driver_master(DRIVER_XE); xe_dev = xe_device_get(fd); igt_assert_f(xe_dev, "Failed to get xe device\n"); kmstest_set_vt_graphics_mode(); + is_vf = intel_is_vf_device(fd); + max_gt = xe_dev_max_gt(fd); + + gt_dirs = malloc((max_gt + 1) * sizeof(*gt_dirs)); + igt_assert(gt_dirs); + for (int i = 0; i <= max_gt; i++) + gt_dirs[i] = -1; + xe_for_each_gt(fd, gt) { + gt_dirs[gt] = igt_debugfs_gt_dir(fd, gt); + igt_assert_f(gt_dirs[gt] >= 0, + "GT%d: failed to open GT debugfs directory\n", + gt); + } } igt_describe("Check required debugfs devnodes exist in the root debugfs directory."); @@ -643,12 +755,44 @@ int igt_main_args("", long_options, help_str, opt_handler, NULL) igt_subtest("info-read") test_info_read(xe_dev); + igt_describe("Check GT debugfs attrs present on all contexts for each GT."); + igt_subtest_with_dynamic("gt-dir") + xe_for_each_gt(fd, gt) + igt_dynamic_f("gt-%d", gt) + test_gt_dir(xe_dev, gt); + + igt_describe("Validate default LRC content for each engine class present on each GT."); + igt_subtest_with_dynamic("gt-default-lrc") + xe_for_each_gt(fd, gt) + igt_dynamic_f("gt-%d", gt) + test_gt_default_lrc(gt); + + igt_describe("Check that PF-only GT debugfs attrs are present for each GT on PF."); + igt_subtest_with_dynamic("gt-dir-pf-only") { + igt_skip_on_f(is_vf, "PF-only attributes not present on VF\n"); + xe_for_each_gt(fd, gt) + igt_dynamic_f("gt-%d", gt) + test_gt_dir_pf_only(xe_dev, gt); + } + + igt_describe("Write an invalid payload to the stats debugfs attribute for each GT."); + igt_subtest_with_dynamic("gt-stats-write") { + igt_require(geteuid() == 0); + xe_for_each_gt(fd, gt) + igt_dynamic_f("gt-%d", gt) + test_gt_stats_write(gt); + } + igt_subtest_with_dynamic("check-gt-reg-sr") xe_for_each_gt(fd, gt) igt_dynamic_f("gt%d", gt) check_gt_reg_sr(fd, gt); igt_fixture() { + xe_for_each_gt(fd, gt) + if (gt_dirs[gt] >= 0) + close(gt_dirs[gt]); + free(gt_dirs); drm_close_driver(fd); } -- 2.43.0