public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH i-g-t v3 0/5] RFC: Add attachments support
@ 2026-04-13 20:17 Zbigniew Kempczyński
  2026-04-13 20:17 ` [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd() Zbigniew Kempczyński
                   ` (8 more replies)
  0 siblings, 9 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Gustavo Sousa, Krzysztof Karas

This series introduces support for hook/test written attachments.
It is somehow limited and stiff but allows to write anything test/hook
wants in attachments directory. File names which occured in attachments
directory are added to results.json.

Series targets our need to include guc logs for failed tests especially
in the point of time when it occurs.

v2: - added clearing of attachments dir in overwrite mode
    - guc-log hook script is now installed to igt datadir/hooks dir
    - added hook-exec-allowlist to selectively execute hook scripts
v3: - drop hook-exec-allowlist in runner, now scripts are filtering
      allowlist on their own
    - add support for attachments in recursive directories

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Gustavo Sousa <gustavo.sousa@intel.com>
Cc: Krzysztof Karas <krzysztof.karas@intel.com>

Zbigniew Kempczyński (5):
  runner: Rename dirfd to avoid clash with dirfd()
  runner: Create attachments directory to use by hooks
  scripts/hooks: Example guc log copy script and allowlist
  runner/resultgen: Add json array create/get helper
  runner/resultgen: Insert attachments list into results.json

 lib/igt_hook.c                    |  4 ++
 runner/executor.c                 | 87 +++++++++++++++++++++++++++----
 runner/executor.h                 |  2 +
 runner/resultgen.c                | 77 +++++++++++++++++++++++++++
 scripts/hooks/guc_copy.allowlist  |  2 +
 scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++
 scripts/meson.build               |  3 ++
 7 files changed, 213 insertions(+), 9 deletions(-)
 create mode 100644 scripts/hooks/guc_copy.allowlist
 create mode 100755 scripts/hooks/guc_copy_on_fail.sh

-- 
2.43.0


^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd()
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
@ 2026-04-13 20:17 ` Zbigniew Kempczyński
  2026-04-14  7:40   ` Krzysztof Karas
  2026-04-13 20:17 ` [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks Zbigniew Kempczyński
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Upcoming change within execute_next_entry() will call dirfd() so
rename local dirfd variable is necessary.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
---
 runner/executor.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/runner/executor.c b/runner/executor.c
index 847abe481a..1485b59d1f 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -1772,7 +1772,7 @@ static int execute_next_entry(struct execute_state *state,
 			      char **abortreason,
 			      bool *abort_already_written)
 {
-	int dirfd;
+	int idirfd;
 	int outputs[_F_LAST];
 	int kmsgfd;
 	int outpipe[2] = { -1, -1 };
@@ -1786,19 +1786,19 @@ static int execute_next_entry(struct execute_state *state,
 
 	snprintf(name, sizeof(name), "%zd", idx);
 	mkdirat(resdirfd, name, 0777);
-	if ((dirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
+	if ((idirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
 		errf("Error accessing individual test result directory\n");
 		return -1;
 	}
 
-	if (!open_output_files(dirfd, outputs, true)) {
+	if (!open_output_files(idirfd, outputs, true)) {
 		errf("Error opening output files\n");
 		result = -1;
 		goto out_dirfd;
 	}
 
 	if (settings->sync) {
-		fsync(dirfd);
+		fsync(idirfd);
 		fsync(resdirfd);
 	}
 
@@ -1900,8 +1900,8 @@ out_pipe:
 	close_outputs(outputs);
 out_dirfd:
 	if (settings->sync)
-		fsync(dirfd);
-	close(dirfd);
+		fsync(idirfd);
+	close(idirfd);
 	if (settings->sync)
 		fsync(resdirfd);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
  2026-04-13 20:17 ` [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd() Zbigniew Kempczyński
@ 2026-04-13 20:17 ` Zbigniew Kempczyński
  2026-04-14  7:34   ` Krzysztof Karas
  2026-04-14 19:27   ` Gustavo Sousa
  2026-04-13 20:17 ` [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist Zbigniew Kempczyński
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Results parsing is currently limited to few predefined files.

Create "attachments" directory and export full path of created directory
to be used within hooks. From now on environment variable
IGT_RUNNER_ATTACHMENTS_DIR become visible when igt_runner is used
to execute tests. This env contains directory where subtests/dynsubtests
may write auxiliary files which finally be included in results.json.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Krzysztof Karas <krzysztof.karas@intel.com>
---
v2: simplify attachment dirname concatenation (Kamil)
    remove files in attachments dir when overwrite is set (Kamil)
v3: unify 'attdir*' variables (Krzysztof)
    do recursive removal in attachments directories (Gustavo)
---
 lib/igt_hook.c    |  4 +++
 runner/executor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++--
 runner/executor.h |  2 ++
 3 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/lib/igt_hook.c b/lib/igt_hook.c
index f86ed56f72..b8f25b6c7a 100644
--- a/lib/igt_hook.c
+++ b/lib/igt_hook.c
@@ -518,5 +518,9 @@ available to the command:\n\
 \n\
 Note that %s can be passed multiple times. Each descriptor is evaluated in turn\n\
 when matching events and running hook commands.\n\
+\n\
+When executed by the igt_runner, environment IGT_RUNNER_ATTACHMENTS_DIR\n\
+is passed additionally to the hook script. It contains directory where\n\
+script may write additional attachments like guc logs, etc.\n\
 ", option_name);
 }
diff --git a/runner/executor.c b/runner/executor.c
index 1485b59d1f..af39b12aea 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -1,6 +1,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <ftw.h>
 #ifdef ANDROID
 #include "android/glib.h"
 #else
@@ -1779,17 +1780,22 @@ static int execute_next_entry(struct execute_state *state,
 	int errpipe[2] = { -1, -1 };
 	int socket[2] = { -1, -1 };
 	int outfd, errfd, socketfd;
-	char name[32];
+	char name[32], attname[32];
+	char attdirname[PATH_MAX];
 	pid_t child;
 	int result;
 	size_t idx = state->next;
 
 	snprintf(name, sizeof(name), "%zd", idx);
+	snprintf(attname, sizeof(attname), "%zd/%s", idx, DIR_ATTACHMENTS);
 	mkdirat(resdirfd, name, 0777);
+	mkdirat(resdirfd, attname, 0777);
 	if ((idirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
 		errf("Error accessing individual test result directory\n");
 		return -1;
 	}
+	snprintf(attdirname, sizeof(attdirname), "%s/%s",
+		 settings->results_path, attname);
 
 	if (!open_output_files(idirfd, outputs, true)) {
 		errf("Error opening output files\n");
@@ -1870,6 +1876,7 @@ static int execute_next_entry(struct execute_state *state,
 			setenv("IGT_RUNNER_SOCKET_FD", envstring, 1);
 		}
 		setenv("IGT_SENTINEL_ON_STDERR", "1", 1);
+		setenv("IGT_RUNNER_ATTACHMENTS_DIR", attdirname, 1);
 
 		execute_test_process(outfd, errfd, socketfd, settings, entry);
 		/* unreachable */
@@ -1948,9 +1955,61 @@ static int remove_file(int dirfd, const char *name)
 	return unlinkat(dirfd, name, 0) && errno != ENOENT;
 }
 
+static int ftw_attachment_removal(const char *fpath, const struct stat *sb,
+				  int typeflag, struct FTW *ftwbuf)
+{
+	(void)sb;
+	(void)ftwbuf;
+
+	if (typeflag == FTW_F) {
+		if (unlink(fpath)) {
+			errf("Cannot remove file %s\n", fpath);
+			return -1;
+		}
+	} else if (typeflag == FTW_DP) {
+		if (rmdir(fpath)) {
+			errf("Cannot remove directory %s\n", fpath);
+			return -1;
+		}
+	} else {
+		errf("Cannot remove %s (unsupported file type)\n", fpath);
+		return -1;
+	}
+
+	return 0;
+}
+
+static bool clear_attachments_dir_recursively(int attdirfd)
+{
+	char attdirname[PATH_MAX];
+	DIR *currdir;
+	int ret;
+
+	currdir = opendir(".");
+	fchdir(attdirfd);
+	getcwd(attdirname, sizeof(attdirname));
+
+	/* Sanity check we're in attachments directory structure */
+	if (!strstr(attdirname, DIR_ATTACHMENTS)) {
+		errf("Cowardly refusing removing in directory which is not "
+		     "attachments directory [currdir: %s]!\n", attdirname);
+		ret = -1;
+		goto out;
+	}
+
+	ret = nftw(attdirname, ftw_attachment_removal, 4, FTW_PHYS | FTW_DEPTH);
+
+out:
+	fchdir(dirfd(currdir));
+	closedir(currdir);
+
+	return ret ? false : true;
+}
+
 static bool clear_test_result_directory(int dirfd)
 {
-	int i;
+	int i, attdirfd;
+	int ret = true;
 
 	for (i = 0; i < _F_LAST; i++) {
 		if (remove_file(dirfd, filenames[i])) {
@@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
 		}
 	}
 
-	return true;
+	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
+		errf("Cannot open attachments directory\n");
+		return false;
+	}
+
+	ret = clear_attachments_dir_recursively(attdirfd);
+	if (!ret)
+		errf("Cannot clear attachments dir recursively\n");
+
+	return ret;
 }
 
 static bool clear_old_results(char *path)
@@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
 			close(dirfd);
 			return false;
 		}
+
 		close(resdirfd);
 		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
 			errf("Warning: Result directory %s contains extra files\n",
diff --git a/runner/executor.h b/runner/executor.h
index 3b1cabcf55..bc6ac80dc4 100644
--- a/runner/executor.h
+++ b/runner/executor.h
@@ -25,6 +25,8 @@ enum {
 	_F_LAST,
 };
 
+#define DIR_ATTACHMENTS "attachments"
+
 bool open_output_files(int dirfd, int *fds, bool write);
 bool open_output_files_rdonly(int dirfd, int *fds);
 void close_outputs(int *fds);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
  2026-04-13 20:17 ` [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd() Zbigniew Kempczyński
  2026-04-13 20:17 ` [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks Zbigniew Kempczyński
@ 2026-04-13 20:17 ` Zbigniew Kempczyński
  2026-04-14  8:06   ` Krzysztof Karas
  2026-04-14 20:33   ` Gustavo Sousa
  2026-04-13 20:17 ` [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper Zbigniew Kempczyński
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

We need to explicitly extract guc logs for failed tests so add hook
script which does it after subtest/dynsubtest execution. As copying to
attachments takes a lot of time do it only for failing subtests.

Adding this hook script to CI will extend execution time much and
using allowlist is necessary. Instead of allowlist argument in the
runner (previous attempt) now script filters such list on its own and
decides when to move forward and do some post-test actions. Such
approach is more flexible but moves decision to script what causes
it is more prone buggy.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Krzysztof Karas <krzysztof.karas@intel.com>
---
v2: install hook to datadir/hooks
v3: migrate allowlist from runner to script
---
 scripts/hooks/guc_copy.allowlist  |  2 ++
 scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
 scripts/meson.build               |  3 ++
 3 files changed, 52 insertions(+)
 create mode 100644 scripts/hooks/guc_copy.allowlist
 create mode 100755 scripts/hooks/guc_copy_on_fail.sh

diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
new file mode 100644
index 0000000000..04cb3f8298
--- /dev/null
+++ b/scripts/hooks/guc_copy.allowlist
@@ -0,0 +1,2 @@
+igt@xe_compute@compute-square
+igt@xe_exec_basic@once-basic@ccs0
diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
new file mode 100755
index 0000000000..595cf5205e
--- /dev/null
+++ b/scripts/hooks/guc_copy_on_fail.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Hook script for copying guc.log.
+# Suggested usage with:
+# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
+
+# Copy only for failed subtests as this is time-consuming
+if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
+	exit 0
+fi
+
+# Process and copy guc logs only for those specified in allowlist
+ALLOWLIST="guc_copy.allowlist"
+scriptdir=$(dirname $(realpath $0))
+
+if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
+	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
+	exit 0
+fi
+
+cd "$IGT_RUNNER_ATTACHMENTS_DIR"
+
+# Look for allowlist in following places:
+# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
+# 2. Try in <scriptdir>
+
+if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
+	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
+else
+	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
+fi
+
+if [ ! -e "${ALLOWLIST_PATH}" ]; then
+	exit 0
+fi
+
+STNAME="${IGT_HOOK_TEST_FULLNAME}"
+echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
+if [ $? -ne 0 ]; then
+	exit 0
+fi
+
+for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do
+	attout=$(echo ${log:23} | sed -e 's/\//_/g')
+	mkdir -p "${STNAME}"
+	cp "$log" "${STNAME}/${attout}"
+done
diff --git a/scripts/meson.build b/scripts/meson.build
index 6e64065c5e..2ce961898d 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -15,3 +15,6 @@ endif
 igt_doc_script = find_program('igt_doc.py', required : build_testplan)
 gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
 generate_iga64_codes = find_program('generate_iga64_codes')
+
+install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
+install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (2 preceding siblings ...)
  2026-04-13 20:17 ` [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist Zbigniew Kempczyński
@ 2026-04-13 20:17 ` Zbigniew Kempczyński
  2026-04-14  8:31   ` Krzysztof Karas
  2026-04-13 20:17 ` [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json Zbigniew Kempczyński
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Upcoming patch which extends results.json to contain attachments
is going to put file list in the array instead of key=value pair.
Add helper which creates/finds array object in json structure.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Krzysztof Karas <krzysztof.karas@intel.com>
---
 runner/resultgen.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/runner/resultgen.c b/runner/resultgen.c
index 29fc5cbb15..f8459385c3 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -271,6 +271,20 @@ static struct json_t *get_or_create_json_object(struct json_t *base, const char
 	return ret;
 }
 
+static struct json_t *get_or_create_json_array(struct json_t *base, const char *key)
+{
+	struct json_t *ret = json_object_get(base, key);
+
+	if (ret)
+		return ret;
+
+	ret = json_array();
+	json_object_set_new(base, key, ret);
+
+	return ret;
+}
+
+
 static void set_result(struct json_t *obj, const char *result)
 {
 	if (!result)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (3 preceding siblings ...)
  2026-04-13 20:17 ` [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper Zbigniew Kempczyński
@ 2026-04-13 20:17 ` Zbigniew Kempczyński
  2026-04-14  9:35   ` Krzysztof Karas
  2026-04-14 21:39   ` Gustavo Sousa
  2026-04-14  1:57 ` ✓ i915.CI.BAT: success for RFC: Add attachments support (rev3) Patchwork
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-13 20:17 UTC (permalink / raw)
  To: igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Add list of filenames which were created by hooks in attachments directory
(like GuC log copy) to results.json for allow presenting it in CI.

Due to lack of userdata pointer in nftw() implementation main json
object is passed via temporary static variable. It shouldn't be the
problem because results.json is created in single thread. This change
is not too elegant but allows to minimize the code change and is
much easier to read comparing to recursive readdir().

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Krzysztof Karas <krzysztof.karas@intel.com>
---
 runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/runner/resultgen.c b/runner/resultgen.c
index f8459385c3..d37f01a433 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -1,11 +1,14 @@
 #include <assert.h>
 #include <ctype.h>
+#include <dirent.h>
 #include <fcntl.h>
+#include <ftw.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <jansson.h>
@@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
 	return true;
 }
 
+struct json_t *tmp_tests;
+static int ftw_attachments_list(const char *fpath, const struct stat *sb,
+				int typeflag, struct FTW *ftwbuf)
+{
+	struct json_t *obj = NULL, *attobj = NULL;
+	(void)sb;
+	(void)ftwbuf;
+
+	if (typeflag == FTW_F) {
+		char *p;
+
+		p = strstr(fpath + 2, "/");
+		if (!p)
+			return -1;
+		*p = '\0'; /* temporary for acquiring the piglit name */
+		obj = get_or_create_json_object(tmp_tests, fpath + 2);
+		attobj = get_or_create_json_array(obj, "attachments");
+		*p = '/'; /* bring '/' back */
+		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
+	} else if (typeflag == FTW_DP) {
+		;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static bool fill_from_attachments(int idirfd, struct json_t *tests)
+{
+	char attname[32];
+	int attdirfd;
+	DIR *currdir;
+	int ret;
+
+	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
+	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
+		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
+		return false;
+	}
+
+	currdir = opendir(".");
+	fchdir(attdirfd);
+
+	/*
+	 * ftw doesn't support passing user data so *tests has to be
+	 * set to some global for being visible in callback function.
+	 * As results.json is not processed in multiple threads it is
+	 * not a big problem.
+	 */
+	tmp_tests = tests;
+	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
+	fchdir(dirfd(currdir));
+
+	return ret ? false : true;
+}
+
 static const char *result_from_exitcode(int exitcode)
 {
 	switch (exitcode) {
@@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
 		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
 	}
 
+	if (!fill_from_attachments(dirfd, results->tests))
+		fprintf(stderr, "Error parsing attachments directory\n");
+
 	override_results(entry->binary, &subtests, results->tests);
 	prune_subtests(settings, entry, &subtests, results->tests);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* ✓ i915.CI.BAT: success for RFC: Add attachments support (rev3)
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (4 preceding siblings ...)
  2026-04-13 20:17 ` [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json Zbigniew Kempczyński
@ 2026-04-14  1:57 ` Patchwork
  2026-04-14  2:03 ` ✓ Xe.CI.BAT: " Patchwork
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 34+ messages in thread
From: Patchwork @ 2026-04-14  1:57 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 4400 bytes --]

== Series Details ==

Series: RFC: Add attachments support (rev3)
URL   : https://patchwork.freedesktop.org/series/163548/
State : success

== Summary ==

CI Bug Log - changes from IGT_8854 -> IGTPW_14974
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/index.html

Participating hosts (42 -> 39)
------------------------------

  Missing    (3): bat-dg2-13 fi-glk-j4005 fi-snb-2520m 

Known issues
------------

  Here are the changes found in IGTPW_14974 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@core_auth@basic-auth:
    - bat-adlp-9:         [PASS][1] -> [DMESG-WARN][2] ([i915#15673])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-adlp-9/igt@core_auth@basic-auth.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-adlp-9/igt@core_auth@basic-auth.html

  * igt@i915_selftest@live:
    - bat-mtlp-8:         [PASS][3] -> [DMESG-FAIL][4] ([i915#12061]) +1 other test dmesg-fail
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-mtlp-8/igt@i915_selftest@live.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-mtlp-8/igt@i915_selftest@live.html

  * igt@i915_selftest@live@sanitycheck:
    - fi-kbl-7567u:       [PASS][5] -> [DMESG-WARN][6] ([i915#13735]) +79 other tests dmesg-warn
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/fi-kbl-7567u/igt@i915_selftest@live@sanitycheck.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/fi-kbl-7567u/igt@i915_selftest@live@sanitycheck.html

  * igt@i915_selftest@live@workarounds:
    - bat-mtlp-9:         [PASS][7] -> [DMESG-FAIL][8] ([i915#12061]) +1 other test dmesg-fail
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-mtlp-9/igt@i915_selftest@live@workarounds.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-mtlp-9/igt@i915_selftest@live@workarounds.html

  * igt@kms_pm_rpm@basic-pci-d3-state:
    - fi-kbl-7567u:       [PASS][9] -> [DMESG-WARN][10] ([i915#13735] / [i915#180]) +53 other tests dmesg-warn
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/fi-kbl-7567u/igt@kms_pm_rpm@basic-pci-d3-state.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/fi-kbl-7567u/igt@kms_pm_rpm@basic-pci-d3-state.html

  
#### Possible fixes ####

  * igt@core_debugfs@read-all-entries:
    - bat-adlp-9:         [DMESG-WARN][11] ([i915#15673]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-adlp-9/igt@core_debugfs@read-all-entries.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-adlp-9/igt@core_debugfs@read-all-entries.html

  * igt@i915_selftest@live@workarounds:
    - bat-dg2-14:         [DMESG-FAIL][13] ([i915#12061]) -> [PASS][14] +1 other test pass
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-dg2-14/igt@i915_selftest@live@workarounds.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-dg2-14/igt@i915_selftest@live@workarounds.html
    - bat-arls-6:         [DMESG-FAIL][15] ([i915#12061]) -> [PASS][16] +1 other test pass
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_8854/bat-arls-6/igt@i915_selftest@live@workarounds.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/bat-arls-6/igt@i915_selftest@live@workarounds.html

  
  [i915#12061]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12061
  [i915#13735]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13735
  [i915#15673]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15673
  [i915#180]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/180


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_8854 -> IGTPW_14974
  * Linux: CI_DRM_18313 -> CI_DRM_18326

  CI-20190529: 20190529
  CI_DRM_18313: 3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5 @ git://anongit.freedesktop.org/gfx-ci/linux
  CI_DRM_18326: c8bad7becc008716c8475847328c549e178c813c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_14974: c162a18a4f192cdf0c0fce512f2e1695605d19db @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  IGT_8854: 93abaf0170728f69bc27577e5b405f7a2a01b6fd @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/index.html

[-- Attachment #2: Type: text/html, Size: 5561 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* ✓ Xe.CI.BAT: success for RFC: Add attachments support (rev3)
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (5 preceding siblings ...)
  2026-04-14  1:57 ` ✓ i915.CI.BAT: success for RFC: Add attachments support (rev3) Patchwork
@ 2026-04-14  2:03 ` Patchwork
  2026-04-14  5:30 ` ✗ Xe.CI.FULL: failure " Patchwork
  2026-04-14  7:59 ` ✓ i915.CI.Full: success " Patchwork
  8 siblings, 0 replies; 34+ messages in thread
From: Patchwork @ 2026-04-14  2:03 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 1170 bytes --]

== Series Details ==

Series: RFC: Add attachments support (rev3)
URL   : https://patchwork.freedesktop.org/series/163548/
State : success

== Summary ==

CI Bug Log - changes from XEIGT_8854_BAT -> XEIGTPW_14974_BAT
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Participating hosts (14 -> 11)
------------------------------

  Missing    (3): bat-dg2-oem2 bat-adlp-vm bat-ptl-vm 


Changes
-------

  No changes found


Build changes
-------------

  * IGT: IGT_8854 -> IGTPW_14974
  * Linux: xe-4884-3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5 -> xe-4897-c8bad7becc008716c8475847328c549e178c813c

  IGTPW_14974: c162a18a4f192cdf0c0fce512f2e1695605d19db @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  IGT_8854: 93abaf0170728f69bc27577e5b405f7a2a01b6fd @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  xe-4884-3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5: 3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5
  xe-4897-c8bad7becc008716c8475847328c549e178c813c: c8bad7becc008716c8475847328c549e178c813c

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/index.html

[-- Attachment #2: Type: text/html, Size: 1729 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* ✗ Xe.CI.FULL: failure for RFC: Add attachments support (rev3)
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (6 preceding siblings ...)
  2026-04-14  2:03 ` ✓ Xe.CI.BAT: " Patchwork
@ 2026-04-14  5:30 ` Patchwork
  2026-04-14  7:59 ` ✓ i915.CI.Full: success " Patchwork
  8 siblings, 0 replies; 34+ messages in thread
From: Patchwork @ 2026-04-14  5:30 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 24965 bytes --]

== Series Details ==

Series: RFC: Add attachments support (rev3)
URL   : https://patchwork.freedesktop.org/series/163548/
State : failure

== Summary ==

CI Bug Log - changes from XEIGT_8854_FULL -> XEIGTPW_14974_FULL
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with XEIGTPW_14974_FULL absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in XEIGTPW_14974_FULL, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Participating hosts (2 -> 2)
------------------------------

  No changes in participating hosts

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in XEIGTPW_14974_FULL:

### IGT changes ###

#### Possible regressions ####

  * igt@device_reset@unbind-reset-rebind:
    - shard-bmg:          [PASS][1] -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-8/igt@device_reset@unbind-reset-rebind.html
   [2]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-7/igt@device_reset@unbind-reset-rebind.html

  * igt@kms_dp_linktrain_fallback@dp-fallback:
    - shard-bmg:          [PASS][3] -> [FAIL][4]
   [3]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-10/igt@kms_dp_linktrain_fallback@dp-fallback.html
   [4]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@kms_dp_linktrain_fallback@dp-fallback.html

  
Known issues
------------

  Here are the changes found in XEIGTPW_14974_FULL that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_atomic_transition@plane-all-modeset-transition-fencing:
    - shard-bmg:          [PASS][5] -> [INCOMPLETE][6] ([Intel XE#2705] / [Intel XE#6819] / [Intel XE#6891] / [Intel XE#6904])
   [5]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-1/igt@kms_atomic_transition@plane-all-modeset-transition-fencing.html
   [6]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@kms_atomic_transition@plane-all-modeset-transition-fencing.html

  * igt@kms_atomic_transition@plane-all-modeset-transition-fencing@pipe-a-dp-2:
    - shard-bmg:          [PASS][7] -> [INCOMPLETE][8] ([Intel XE#2705] / [Intel XE#6819])
   [7]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-1/igt@kms_atomic_transition@plane-all-modeset-transition-fencing@pipe-a-dp-2.html
   [8]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@kms_atomic_transition@plane-all-modeset-transition-fencing@pipe-a-dp-2.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip:
    - shard-lnl:          NOTRUN -> [SKIP][9] ([Intel XE#3658] / [Intel XE#7360])
   [9]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-2/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180:
    - shard-bmg:          NOTRUN -> [SKIP][10] ([Intel XE#1124])
   [10]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-8/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180.html

  * igt@kms_ccs@crc-primary-suspend-4-tiled-mtl-rc-ccs:
    - shard-lnl:          NOTRUN -> [SKIP][11] ([Intel XE#3432])
   [11]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@kms_ccs@crc-primary-suspend-4-tiled-mtl-rc-ccs.html

  * igt@kms_ccs@crc-sprite-planes-basic-yf-tiled-ccs:
    - shard-bmg:          NOTRUN -> [SKIP][12] ([Intel XE#2887]) +2 other tests skip
   [12]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-8/igt@kms_ccs@crc-sprite-planes-basic-yf-tiled-ccs.html

  * igt@kms_chamelium_color@ctm-green-to-red:
    - shard-lnl:          NOTRUN -> [SKIP][13] ([Intel XE#306] / [Intel XE#7358])
   [13]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-7/igt@kms_chamelium_color@ctm-green-to-red.html

  * igt@kms_chamelium_hpd@dp-hpd-after-suspend:
    - shard-bmg:          NOTRUN -> [SKIP][14] ([Intel XE#2252])
   [14]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-9/igt@kms_chamelium_hpd@dp-hpd-after-suspend.html

  * igt@kms_cursor_crc@cursor-offscreen-256x85:
    - shard-bmg:          NOTRUN -> [SKIP][15] ([Intel XE#2320]) +1 other test skip
   [15]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-10/igt@kms_cursor_crc@cursor-offscreen-256x85.html

  * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
    - shard-lnl:          NOTRUN -> [SKIP][16] ([Intel XE#309] / [Intel XE#7343])
   [16]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_dirtyfb@drrs-dirtyfb-ioctl:
    - shard-lnl:          NOTRUN -> [SKIP][17] ([Intel XE#1508])
   [17]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-4/igt@kms_dirtyfb@drrs-dirtyfb-ioctl.html

  * igt@kms_flip@2x-blocking-absolute-wf_vblank:
    - shard-lnl:          NOTRUN -> [SKIP][18] ([Intel XE#1421]) +1 other test skip
   [18]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-2/igt@kms_flip@2x-blocking-absolute-wf_vblank.html

  * igt@kms_flip_scaled_crc@flip-p016-linear-to-p016-linear-reflect-x:
    - shard-bmg:          NOTRUN -> [SKIP][19] ([Intel XE#7179])
   [19]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-9/igt@kms_flip_scaled_crc@flip-p016-linear-to-p016-linear-reflect-x.html

  * igt@kms_frontbuffer_tracking@drrs-1p-offscreen-pri-shrfb-draw-mmap-wc:
    - shard-lnl:          NOTRUN -> [SKIP][20] ([Intel XE#6312])
   [20]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@kms_frontbuffer_tracking@drrs-1p-offscreen-pri-shrfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt:
    - shard-bmg:          NOTRUN -> [SKIP][21] ([Intel XE#4141])
   [21]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-10/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-fullscreen:
    - shard-bmg:          NOTRUN -> [SKIP][22] ([Intel XE#2311]) +3 other tests skip
   [22]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-5/igt@kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-fullscreen.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-indfb-plflip-blt:
    - shard-bmg:          NOTRUN -> [SKIP][23] ([Intel XE#2313]) +3 other tests skip
   [23]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-10/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-indfb-plflip-blt.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-shrfb-plflip-blt:
    - shard-lnl:          NOTRUN -> [SKIP][24] ([Intel XE#656]) +3 other tests skip
   [24]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-8/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-shrfb-plflip-blt.html

  * igt@kms_frontbuffer_tracking@psr-argb161616f-draw-mmap-wc:
    - shard-bmg:          NOTRUN -> [SKIP][25] ([Intel XE#7061] / [Intel XE#7356])
   [25]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-2/igt@kms_frontbuffer_tracking@psr-argb161616f-draw-mmap-wc.html

  * igt@kms_joiner@basic-ultra-joiner:
    - shard-bmg:          NOTRUN -> [SKIP][26] ([Intel XE#6911] / [Intel XE#7378])
   [26]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-5/igt@kms_joiner@basic-ultra-joiner.html

  * igt@kms_joiner@invalid-modeset-ultra-joiner:
    - shard-lnl:          NOTRUN -> [SKIP][27] ([Intel XE#6900] / [Intel XE#7362])
   [27]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-1/igt@kms_joiner@invalid-modeset-ultra-joiner.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-lnl:          NOTRUN -> [SKIP][28] ([Intel XE#7591])
   [28]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-7/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_plane@pixel-format-4-tiled-dg2-rc-ccs-modifier:
    - shard-lnl:          NOTRUN -> [SKIP][29] ([Intel XE#7283])
   [29]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-5/igt@kms_plane@pixel-format-4-tiled-dg2-rc-ccs-modifier.html

  * igt@kms_plane@pixel-format-4-tiled-lnl-ccs-modifier:
    - shard-bmg:          NOTRUN -> [SKIP][30] ([Intel XE#7283]) +1 other test skip
   [30]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-6/igt@kms_plane@pixel-format-4-tiled-lnl-ccs-modifier.html

  * igt@kms_pm_dc@dc5-dpms:
    - shard-lnl:          NOTRUN -> [FAIL][31] ([Intel XE#7340] / [Intel XE#7504])
   [31]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-7/igt@kms_pm_dc@dc5-dpms.html

  * igt@kms_psr@fbc-psr-sprite-render:
    - shard-bmg:          NOTRUN -> [SKIP][32] ([Intel XE#2234] / [Intel XE#2850])
   [32]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-8/igt@kms_psr@fbc-psr-sprite-render.html

  * igt@kms_psr@pr-sprite-render:
    - shard-lnl:          NOTRUN -> [SKIP][33] ([Intel XE#1406])
   [33]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-5/igt@kms_psr@pr-sprite-render.html

  * igt@kms_rotation_crc@bad-tiling:
    - shard-lnl:          NOTRUN -> [SKIP][34] ([Intel XE#3414] / [Intel XE#3904] / [Intel XE#7342])
   [34]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-7/igt@kms_rotation_crc@bad-tiling.html

  * igt@kms_rotation_crc@primary-yf-tiled-reflect-x-0:
    - shard-lnl:          NOTRUN -> [SKIP][35] ([Intel XE#1127] / [Intel XE#5813])
   [35]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-7/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-0.html

  * igt@kms_sharpness_filter@filter-scaler-upscale:
    - shard-bmg:          NOTRUN -> [SKIP][36] ([Intel XE#6503])
   [36]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-9/igt@kms_sharpness_filter@filter-scaler-upscale.html

  * igt@xe_compute@ccs-mode-basic:
    - shard-lnl:          NOTRUN -> [SKIP][37] ([Intel XE#1447] / [Intel XE#7471])
   [37]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-6/igt@xe_compute@ccs-mode-basic.html

  * igt@xe_configfs@ctx-restore-post-bb:
    - shard-bmg:          [PASS][38] -> [DMESG-WARN][39] ([Intel XE#7725])
   [38]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-7/igt@xe_configfs@ctx-restore-post-bb.html
   [39]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-6/igt@xe_configfs@ctx-restore-post-bb.html

  * igt@xe_eudebug_online@writes-caching-sram-bb-vram-target-sram:
    - shard-bmg:          NOTRUN -> [SKIP][40] ([Intel XE#7636])
   [40]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-8/igt@xe_eudebug_online@writes-caching-sram-bb-vram-target-sram.html

  * igt@xe_evict@evict-beng-cm-threads-small:
    - shard-lnl:          NOTRUN -> [SKIP][41] ([Intel XE#6540] / [Intel XE#688]) +2 other tests skip
   [41]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-4/igt@xe_evict@evict-beng-cm-threads-small.html

  * igt@xe_evict@evict-small-external-multi-queue-cm:
    - shard-bmg:          NOTRUN -> [SKIP][42] ([Intel XE#7140])
   [42]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-5/igt@xe_evict@evict-small-external-multi-queue-cm.html

  * igt@xe_exec_balancer@many-execqueues-cm-parallel-userptr-rebind:
    - shard-lnl:          NOTRUN -> [SKIP][43] ([Intel XE#7482]) +1 other test skip
   [43]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@xe_exec_balancer@many-execqueues-cm-parallel-userptr-rebind.html

  * igt@xe_exec_basic@multigpu-many-execqueues-many-vm-basic-defer-mmap:
    - shard-bmg:          NOTRUN -> [SKIP][44] ([Intel XE#2322] / [Intel XE#7372]) +1 other test skip
   [44]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-2/igt@xe_exec_basic@multigpu-many-execqueues-many-vm-basic-defer-mmap.html

  * igt@xe_exec_basic@multigpu-once-bindexecqueue-userptr:
    - shard-lnl:          NOTRUN -> [SKIP][45] ([Intel XE#1392])
   [45]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-6/igt@xe_exec_basic@multigpu-once-bindexecqueue-userptr.html

  * igt@xe_exec_fault_mode@many-execqueues-multi-queue-imm:
    - shard-bmg:          NOTRUN -> [SKIP][46] ([Intel XE#7136]) +2 other tests skip
   [46]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-8/igt@xe_exec_fault_mode@many-execqueues-multi-queue-imm.html

  * igt@xe_exec_multi_queue@many-queues-close-fd:
    - shard-bmg:          NOTRUN -> [SKIP][47] ([Intel XE#6874]) +1 other test skip
   [47]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-5/igt@xe_exec_multi_queue@many-queues-close-fd.html

  * igt@xe_exec_multi_queue@one-queue-preempt-mode-fault-basic:
    - shard-lnl:          NOTRUN -> [SKIP][48] ([Intel XE#6874]) +3 other tests skip
   [48]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@xe_exec_multi_queue@one-queue-preempt-mode-fault-basic.html

  * igt@xe_exec_system_allocator@pat-index-madvise-pat-idx-uc-single-vma:
    - shard-lnl:          [PASS][49] -> [FAIL][50] ([Intel XE#5625])
   [49]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-lnl-5/igt@xe_exec_system_allocator@pat-index-madvise-pat-idx-uc-single-vma.html
   [50]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-2/igt@xe_exec_system_allocator@pat-index-madvise-pat-idx-uc-single-vma.html

  * igt@xe_exec_threads@threads-multi-queue-cm-shared-vm-userptr-invalidate:
    - shard-bmg:          NOTRUN -> [SKIP][51] ([Intel XE#7138]) +1 other test skip
   [51]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-6/igt@xe_exec_threads@threads-multi-queue-cm-shared-vm-userptr-invalidate.html

  * igt@xe_exec_threads@threads-multi-queue-fd-userptr-invalidate:
    - shard-lnl:          NOTRUN -> [SKIP][52] ([Intel XE#7138]) +1 other test skip
   [52]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@xe_exec_threads@threads-multi-queue-fd-userptr-invalidate.html

  * igt@xe_fault_injection@vm-bind-fail-vm_bind_ioctl_ops_create:
    - shard-bmg:          NOTRUN -> [ABORT][53] ([Intel XE#7578])
   [53]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-1/igt@xe_fault_injection@vm-bind-fail-vm_bind_ioctl_ops_create.html

  * igt@xe_prefetch_fault@prefetch-fault-svm:
    - shard-bmg:          NOTRUN -> [SKIP][54] ([Intel XE#7599])
   [54]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@xe_prefetch_fault@prefetch-fault-svm.html

  * igt@xe_query@multigpu-query-topology-l3-bank-mask:
    - shard-lnl:          NOTRUN -> [SKIP][55] ([Intel XE#944]) +1 other test skip
   [55]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-4/igt@xe_query@multigpu-query-topology-l3-bank-mask.html

  * igt@xe_sriov_auto_provisioning@selfconfig-reprovision-reduce-numvfs:
    - shard-lnl:          NOTRUN -> [SKIP][56] ([Intel XE#4130] / [Intel XE#7366])
   [56]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-3/igt@xe_sriov_auto_provisioning@selfconfig-reprovision-reduce-numvfs.html

  
#### Possible fixes ####

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic:
    - shard-bmg:          [FAIL][57] ([Intel XE#7571]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-7/igt@kms_cursor_legacy@flip-vs-cursor-atomic.html
   [58]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@kms_cursor_legacy@flip-vs-cursor-atomic.html

  * igt@kms_hdmi_inject@inject-audio:
    - shard-bmg:          [SKIP][59] ([Intel XE#7308]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-1/igt@kms_hdmi_inject@inject-audio.html
   [60]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@kms_hdmi_inject@inject-audio.html

  * igt@kms_hdr@invalid-hdr:
    - shard-bmg:          [SKIP][61] ([Intel XE#1503]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-2/igt@kms_hdr@invalid-hdr.html
   [62]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-1/igt@kms_hdr@invalid-hdr.html

  * igt@kms_vrr@max-min@pipe-a-edp-1:
    - shard-lnl:          [FAIL][63] ([Intel XE#4227]) -> [PASS][64] +1 other test pass
   [63]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-lnl-1/igt@kms_vrr@max-min@pipe-a-edp-1.html
   [64]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-lnl-2/igt@kms_vrr@max-min@pipe-a-edp-1.html

  * igt@xe_configfs@engines-allowed:
    - shard-bmg:          [DMESG-WARN][65] ([Intel XE#7725]) -> [PASS][66] +3 other tests pass
   [65]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-6/igt@xe_configfs@engines-allowed.html
   [66]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-1/igt@xe_configfs@engines-allowed.html

  * igt@xe_sriov_auto_provisioning@resources-released-on-vfs-disabling@numvfs-random:
    - shard-bmg:          [FAIL][67] ([Intel XE#5937]) -> [PASS][68] +1 other test pass
   [67]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-3/igt@xe_sriov_auto_provisioning@resources-released-on-vfs-disabling@numvfs-random.html
   [68]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-3/igt@xe_sriov_auto_provisioning@resources-released-on-vfs-disabling@numvfs-random.html

  * igt@xe_sriov_flr@flr-twice:
    - shard-bmg:          [FAIL][69] ([Intel XE#6569]) -> [PASS][70]
   [69]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-8/igt@xe_sriov_flr@flr-twice.html
   [70]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-1/igt@xe_sriov_flr@flr-twice.html

  
#### Warnings ####

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move:
    - shard-bmg:          [SKIP][71] ([Intel XE#2312]) -> [SKIP][72] ([Intel XE#2313])
   [71]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-6/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html
   [72]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-9/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html

  * igt@kms_tiled_display@basic-test-pattern-with-chamelium:
    - shard-bmg:          [SKIP][73] ([Intel XE#2426] / [Intel XE#5848]) -> [SKIP][74] ([Intel XE#2509] / [Intel XE#7437])
   [73]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_8854/shard-bmg-7/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html
   [74]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/shard-bmg-2/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html

  
  [Intel XE#1124]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1124
  [Intel XE#1127]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1127
  [Intel XE#1392]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1392
  [Intel XE#1406]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1406
  [Intel XE#1421]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1421
  [Intel XE#1447]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1447
  [Intel XE#1503]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1503
  [Intel XE#1508]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1508
  [Intel XE#2234]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2234
  [Intel XE#2252]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2252
  [Intel XE#2311]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2311
  [Intel XE#2312]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2312
  [Intel XE#2313]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2313
  [Intel XE#2320]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2320
  [Intel XE#2322]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2322
  [Intel XE#2426]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2426
  [Intel XE#2509]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2509
  [Intel XE#2705]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2705
  [Intel XE#2850]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2850
  [Intel XE#2887]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2887
  [Intel XE#306]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/306
  [Intel XE#309]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/309
  [Intel XE#3414]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/3414
  [Intel XE#3432]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/3432
  [Intel XE#3658]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/3658
  [Intel XE#3904]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/3904
  [Intel XE#4130]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/4130
  [Intel XE#4141]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/4141
  [Intel XE#4227]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/4227
  [Intel XE#5625]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/5625
  [Intel XE#5813]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/5813
  [Intel XE#5848]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/5848
  [Intel XE#5937]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/5937
  [Intel XE#6312]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6312
  [Intel XE#6503]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6503
  [Intel XE#6540]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6540
  [Intel XE#656]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/656
  [Intel XE#6569]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6569
  [Intel XE#6819]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6819
  [Intel XE#6874]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6874
  [Intel XE#688]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/688
  [Intel XE#6891]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6891
  [Intel XE#6900]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6900
  [Intel XE#6904]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6904
  [Intel XE#6911]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6911
  [Intel XE#7061]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7061
  [Intel XE#7136]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7136
  [Intel XE#7138]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7138
  [Intel XE#7140]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7140
  [Intel XE#7179]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7179
  [Intel XE#7283]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7283
  [Intel XE#7308]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7308
  [Intel XE#7340]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7340
  [Intel XE#7342]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7342
  [Intel XE#7343]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7343
  [Intel XE#7356]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7356
  [Intel XE#7358]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7358
  [Intel XE#7360]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7360
  [Intel XE#7362]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7362
  [Intel XE#7366]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7366
  [Intel XE#7372]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7372
  [Intel XE#7378]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7378
  [Intel XE#7437]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7437
  [Intel XE#7471]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7471
  [Intel XE#7482]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7482
  [Intel XE#7504]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7504
  [Intel XE#7571]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7571
  [Intel XE#7578]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7578
  [Intel XE#7591]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7591
  [Intel XE#7599]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7599
  [Intel XE#7636]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7636
  [Intel XE#7725]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7725
  [Intel XE#944]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/944


Build changes
-------------

  * IGT: IGT_8854 -> IGTPW_14974
  * Linux: xe-4884-3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5 -> xe-4897-c8bad7becc008716c8475847328c549e178c813c

  IGTPW_14974: c162a18a4f192cdf0c0fce512f2e1695605d19db @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  IGT_8854: 93abaf0170728f69bc27577e5b405f7a2a01b6fd @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  xe-4884-3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5: 3751e2e5a19aba3949a3f12aa5b917eb8bbb1eb5
  xe-4897-c8bad7becc008716c8475847328c549e178c813c: c8bad7becc008716c8475847328c549e178c813c

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_14974/index.html

[-- Attachment #2: Type: text/html, Size: 27246 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-13 20:17 ` [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks Zbigniew Kempczyński
@ 2026-04-14  7:34   ` Krzysztof Karas
  2026-04-14 19:13     ` Zbigniew Kempczyński
  2026-04-14 19:27   ` Gustavo Sousa
  1 sibling, 1 reply; 34+ messages in thread
From: Krzysztof Karas @ 2026-04-14  7:34 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

Hi Zbigniew,

[...]

>  static bool clear_test_result_directory(int dirfd)
>  {
> -	int i;
> +	int i, attdirfd;
> +	int ret = true;
>  
>  	for (i = 0; i < _F_LAST; i++) {
>  		if (remove_file(dirfd, filenames[i])) {
> @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
>  		}
>  	}
>  
> -	return true;
> +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> +		errf("Cannot open attachments directory\n");
> +		return false;
> +	}
> +
> +	ret = clear_attachments_dir_recursively(attdirfd);
> +	if (!ret)
> +		errf("Cannot clear attachments dir recursively\n");
> +
> +	return ret;
>  }
>  
>  static bool clear_old_results(char *path)
> @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
>  			close(dirfd);
>  			return false;
>  		}
> +
This is an unrelated newline, but I'd not block over it:
Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>

>  		close(resdirfd);
>  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
>  			errf("Warning: Result directory %s contains extra files\n",
> diff --git a/runner/executor.h b/runner/executor.h
> index 3b1cabcf55..bc6ac80dc4 100644
> --- a/runner/executor.h
> +++ b/runner/executor.h
> @@ -25,6 +25,8 @@ enum {
>  	_F_LAST,
>  };
>  
> +#define DIR_ATTACHMENTS "attachments"
> +
>  bool open_output_files(int dirfd, int *fds, bool write);
>  bool open_output_files_rdonly(int dirfd, int *fds);
>  void close_outputs(int *fds);
> -- 
> 2.43.0
> 

-- 
Best Regards,
Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd()
  2026-04-13 20:17 ` [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd() Zbigniew Kempczyński
@ 2026-04-14  7:40   ` Krzysztof Karas
  0 siblings, 0 replies; 34+ messages in thread
From: Krzysztof Karas @ 2026-04-14  7:40 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

Hi Zbigniew,

> Upcoming change within execute_next_entry() will call dirfd() so
> rename local dirfd variable is necessary.
> 
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
>  runner/executor.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>

-- 
Best Regards,
Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* ✓ i915.CI.Full: success for RFC: Add attachments support (rev3)
  2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
                   ` (7 preceding siblings ...)
  2026-04-14  5:30 ` ✗ Xe.CI.FULL: failure " Patchwork
@ 2026-04-14  7:59 ` Patchwork
  8 siblings, 0 replies; 34+ messages in thread
From: Patchwork @ 2026-04-14  7:59 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 130852 bytes --]

== Series Details ==

Series: RFC: Add attachments support (rev3)
URL   : https://patchwork.freedesktop.org/series/163548/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_18326_full -> IGTPW_14974_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/index.html

Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts

Known issues
------------

  Here are the changes found in IGTPW_14974_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@device_reset@unbind-cold-reset-rebind:
    - shard-rkl:          NOTRUN -> [SKIP][1] ([i915#11078])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@device_reset@unbind-cold-reset-rebind.html

  * igt@gem_busy@semaphore:
    - shard-dg2:          NOTRUN -> [SKIP][2] ([i915#3936])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@gem_busy@semaphore.html
    - shard-dg1:          NOTRUN -> [SKIP][3] ([i915#3936])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@gem_busy@semaphore.html
    - shard-mtlp:         NOTRUN -> [SKIP][4] ([i915#3936])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@gem_busy@semaphore.html

  * igt@gem_ccs@block-multicopy-inplace:
    - shard-tglu-1:       NOTRUN -> [SKIP][5] ([i915#3555] / [i915#9323])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@gem_ccs@block-multicopy-inplace.html

  * igt@gem_ccs@suspend-resume:
    - shard-dg2:          NOTRUN -> [INCOMPLETE][6] ([i915#13356])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@gem_ccs@suspend-resume.html
    - shard-rkl:          NOTRUN -> [SKIP][7] ([i915#9323]) +1 other test skip
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@gem_ccs@suspend-resume.html
    - shard-dg1:          NOTRUN -> [SKIP][8] ([i915#9323]) +1 other test skip
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@gem_ccs@suspend-resume.html
    - shard-tglu:         NOTRUN -> [SKIP][9] ([i915#9323]) +1 other test skip
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@gem_ccs@suspend-resume.html
    - shard-mtlp:         NOTRUN -> [SKIP][10] ([i915#9323]) +1 other test skip
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-8/igt@gem_ccs@suspend-resume.html

  * igt@gem_ccs@suspend-resume@tile4-compressed-compfmt0-lmem0-lmem0:
    - shard-dg2:          NOTRUN -> [INCOMPLETE][11] ([i915#12392] / [i915#13356])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@gem_ccs@suspend-resume@tile4-compressed-compfmt0-lmem0-lmem0.html

  * igt@gem_create@create-ext-cpu-access-big:
    - shard-dg2:          [PASS][12] -> [FAIL][13] ([i915#15454])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-8/igt@gem_create@create-ext-cpu-access-big.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@gem_create@create-ext-cpu-access-big.html

  * igt@gem_create@create-ext-cpu-access-sanity-check:
    - shard-tglu:         NOTRUN -> [SKIP][14] ([i915#6335])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-7/igt@gem_create@create-ext-cpu-access-sanity-check.html

  * igt@gem_ctx_persistence@heartbeat-hang:
    - shard-dg1:          NOTRUN -> [SKIP][15] ([i915#8555])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@gem_ctx_persistence@heartbeat-hang.html

  * igt@gem_ctx_sseu@invalid-args:
    - shard-tglu-1:       NOTRUN -> [SKIP][16] ([i915#280])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@gem_ctx_sseu@invalid-args.html

  * igt@gem_eio@in-flight-suspend:
    - shard-glk:          NOTRUN -> [INCOMPLETE][17] ([i915#13390])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk3/igt@gem_eio@in-flight-suspend.html

  * igt@gem_eio@kms:
    - shard-rkl:          [PASS][18] -> [DMESG-WARN][19] ([i915#13363])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@gem_eio@kms.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@gem_eio@kms.html
    - shard-tglu:         [PASS][20] -> [ABORT][21] ([i915#13363])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-8/igt@gem_eio@kms.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@gem_eio@kms.html

  * igt@gem_exec_balancer@bonded-true-hang:
    - shard-dg2:          NOTRUN -> [SKIP][22] ([i915#4812]) +1 other test skip
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@gem_exec_balancer@bonded-true-hang.html

  * igt@gem_exec_balancer@parallel-keep-submit-fence:
    - shard-tglu-1:       NOTRUN -> [SKIP][23] ([i915#4525]) +1 other test skip
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@gem_exec_balancer@parallel-keep-submit-fence.html

  * igt@gem_exec_balancer@parallel-ordering:
    - shard-rkl:          NOTRUN -> [SKIP][24] ([i915#4525])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@gem_exec_balancer@parallel-ordering.html
    - shard-tglu:         NOTRUN -> [SKIP][25] ([i915#4525]) +1 other test skip
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@gem_exec_balancer@parallel-ordering.html

  * igt@gem_exec_big@single:
    - shard-tglu:         [PASS][26] -> [FAIL][27] ([i915#15816])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-9/igt@gem_exec_big@single.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@gem_exec_big@single.html

  * igt@gem_exec_capture@capture-invisible:
    - shard-glk11:        NOTRUN -> [SKIP][28] ([i915#6334]) +1 other test skip
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@gem_exec_capture@capture-invisible.html

  * igt@gem_exec_fence@submit67:
    - shard-dg1:          NOTRUN -> [SKIP][29] ([i915#4812]) +1 other test skip
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-17/igt@gem_exec_fence@submit67.html
    - shard-mtlp:         NOTRUN -> [SKIP][30] ([i915#4812]) +1 other test skip
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@gem_exec_fence@submit67.html

  * igt@gem_exec_fence@syncobj-backward-timeline-chain-engines:
    - shard-snb:          NOTRUN -> [SKIP][31] +118 other tests skip
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-snb4/igt@gem_exec_fence@syncobj-backward-timeline-chain-engines.html

  * igt@gem_exec_flush@basic-batch-kernel-default-uc:
    - shard-dg2:          NOTRUN -> [SKIP][32] ([i915#3539] / [i915#4852])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@gem_exec_flush@basic-batch-kernel-default-uc.html

  * igt@gem_exec_flush@basic-wb-rw-before-default:
    - shard-dg1:          NOTRUN -> [SKIP][33] ([i915#3539] / [i915#4852]) +1 other test skip
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@gem_exec_flush@basic-wb-rw-before-default.html

  * igt@gem_exec_reloc@basic-wc-cpu:
    - shard-dg2:          NOTRUN -> [SKIP][34] ([i915#3281]) +2 other tests skip
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-10/igt@gem_exec_reloc@basic-wc-cpu.html
    - shard-rkl:          NOTRUN -> [SKIP][35] ([i915#3281]) +4 other tests skip
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@gem_exec_reloc@basic-wc-cpu.html
    - shard-mtlp:         NOTRUN -> [SKIP][36] ([i915#3281]) +4 other tests skip
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@gem_exec_reloc@basic-wc-cpu.html

  * igt@gem_exec_reloc@basic-write-cpu-active:
    - shard-dg1:          NOTRUN -> [SKIP][37] ([i915#3281]) +5 other tests skip
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-13/igt@gem_exec_reloc@basic-write-cpu-active.html

  * igt@gem_exec_schedule@preempt-queue-chain:
    - shard-mtlp:         NOTRUN -> [SKIP][38] ([i915#4537] / [i915#4812])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@gem_exec_schedule@preempt-queue-chain.html
    - shard-dg2:          NOTRUN -> [SKIP][39] ([i915#4537] / [i915#4812])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@gem_exec_schedule@preempt-queue-chain.html

  * igt@gem_exec_suspend@basic-s3:
    - shard-rkl:          [PASS][40] -> [INCOMPLETE][41] ([i915#13356]) +1 other test incomplete
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@gem_exec_suspend@basic-s3.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_exec_suspend@basic-s3.html

  * igt@gem_lmem_evict@dontneed-evict-race:
    - shard-rkl:          NOTRUN -> [SKIP][42] ([i915#4613] / [i915#7582])
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@gem_lmem_evict@dontneed-evict-race.html
    - shard-tglu:         NOTRUN -> [SKIP][43] ([i915#4613] / [i915#7582])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-10/igt@gem_lmem_evict@dontneed-evict-race.html

  * igt@gem_lmem_swapping@heavy-verify-random-ccs:
    - shard-dg1:          NOTRUN -> [SKIP][44] ([i915#12193]) +1 other test skip
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@gem_lmem_swapping@heavy-verify-random-ccs.html

  * igt@gem_lmem_swapping@heavy-verify-random-ccs@lmem0:
    - shard-dg1:          NOTRUN -> [SKIP][45] ([i915#4565]) +1 other test skip
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@gem_lmem_swapping@heavy-verify-random-ccs@lmem0.html

  * igt@gem_lmem_swapping@parallel-random:
    - shard-glk:          NOTRUN -> [SKIP][46] ([i915#4613]) +4 other tests skip
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk1/igt@gem_lmem_swapping@parallel-random.html

  * igt@gem_lmem_swapping@smem-oom:
    - shard-tglu:         NOTRUN -> [SKIP][47] ([i915#4613]) +1 other test skip
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-9/igt@gem_lmem_swapping@smem-oom.html
    - shard-mtlp:         NOTRUN -> [SKIP][48] ([i915#4613]) +2 other tests skip
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-7/igt@gem_lmem_swapping@smem-oom.html

  * igt@gem_lmem_swapping@verify:
    - shard-rkl:          NOTRUN -> [SKIP][49] ([i915#4613]) +2 other tests skip
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@gem_lmem_swapping@verify.html

  * igt@gem_media_fill@media-fill:
    - shard-mtlp:         NOTRUN -> [SKIP][50] ([i915#8289])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@gem_media_fill@media-fill.html
    - shard-dg2:          NOTRUN -> [SKIP][51] ([i915#8289])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@gem_media_fill@media-fill.html

  * igt@gem_mmap_gtt@basic:
    - shard-mtlp:         NOTRUN -> [SKIP][52] ([i915#4077]) +4 other tests skip
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-2/igt@gem_mmap_gtt@basic.html

  * igt@gem_mmap_gtt@medium-copy-xy:
    - shard-dg1:          NOTRUN -> [SKIP][53] ([i915#4077]) +4 other tests skip
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@gem_mmap_gtt@medium-copy-xy.html

  * igt@gem_mmap_wc@coherency:
    - shard-dg2:          NOTRUN -> [SKIP][54] ([i915#4083]) +3 other tests skip
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@gem_mmap_wc@coherency.html
    - shard-dg1:          NOTRUN -> [SKIP][55] ([i915#4083]) +1 other test skip
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@gem_mmap_wc@coherency.html
    - shard-mtlp:         NOTRUN -> [SKIP][56] ([i915#4083]) +1 other test skip
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@gem_mmap_wc@coherency.html

  * igt@gem_partial_pwrite_pread@writes-after-reads:
    - shard-dg1:          NOTRUN -> [SKIP][57] ([i915#3282]) +3 other tests skip
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@gem_partial_pwrite_pread@writes-after-reads.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-glk10:        NOTRUN -> [WARN][58] ([i915#14702] / [i915#2658])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk10/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pxp@display-protected-crc:
    - shard-dg2:          NOTRUN -> [SKIP][59] ([i915#4270]) +1 other test skip
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@gem_pxp@display-protected-crc.html
    - shard-dg1:          NOTRUN -> [SKIP][60] ([i915#4270]) +1 other test skip
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@gem_pxp@display-protected-crc.html

  * igt@gem_pxp@hw-rejects-pxp-context:
    - shard-tglu:         NOTRUN -> [SKIP][61] ([i915#13398])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@gem_pxp@hw-rejects-pxp-context.html

  * igt@gem_pxp@verify-pxp-execution-after-suspend-resume:
    - shard-rkl:          [PASS][62] -> [SKIP][63] ([i915#4270])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@gem_pxp@verify-pxp-execution-after-suspend-resume.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@gem_pxp@verify-pxp-execution-after-suspend-resume.html

  * igt@gem_readwrite@beyond-eob:
    - shard-rkl:          NOTRUN -> [SKIP][64] ([i915#3282]) +5 other tests skip
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@gem_readwrite@beyond-eob.html

  * igt@gem_readwrite@write-bad-handle:
    - shard-dg2:          NOTRUN -> [SKIP][65] ([i915#3282]) +1 other test skip
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@gem_readwrite@write-bad-handle.html
    - shard-mtlp:         NOTRUN -> [SKIP][66] ([i915#3282]) +1 other test skip
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@gem_readwrite@write-bad-handle.html

  * igt@gem_render_copy@yf-tiled-ccs-to-y-tiled:
    - shard-dg2:          NOTRUN -> [SKIP][67] ([i915#5190] / [i915#8428]) +1 other test skip
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html
    - shard-mtlp:         NOTRUN -> [SKIP][68] ([i915#8428]) +1 other test skip
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html

  * igt@gem_render_tiled_blits@basic:
    - shard-dg2:          NOTRUN -> [SKIP][69] ([i915#4079])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@gem_render_tiled_blits@basic.html
    - shard-dg1:          NOTRUN -> [SKIP][70] ([i915#4079])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@gem_render_tiled_blits@basic.html
    - shard-mtlp:         NOTRUN -> [SKIP][71] ([i915#4079])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@gem_render_tiled_blits@basic.html

  * igt@gem_set_tiling_vs_blt@untiled-to-tiled:
    - shard-rkl:          NOTRUN -> [SKIP][72] ([i915#8411])
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@gem_set_tiling_vs_blt@untiled-to-tiled.html

  * igt@gem_softpin@noreloc-s3:
    - shard-glk:          NOTRUN -> [INCOMPLETE][73] ([i915#13809])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk9/igt@gem_softpin@noreloc-s3.html
    - shard-rkl:          [PASS][74] -> [INCOMPLETE][75] ([i915#13809])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@gem_softpin@noreloc-s3.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_softpin@noreloc-s3.html

  * igt@gem_tiled_partial_pwrite_pread@reads:
    - shard-dg2:          NOTRUN -> [SKIP][76] ([i915#4077]) +2 other tests skip
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@gem_tiled_partial_pwrite_pread@reads.html

  * igt@gem_tiled_partial_pwrite_pread@writes-after-reads:
    - shard-rkl:          NOTRUN -> [SKIP][77] ([i915#14544] / [i915#3282])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_tiled_partial_pwrite_pread@writes-after-reads.html

  * igt@gem_tiled_pread_basic@basic:
    - shard-dg1:          NOTRUN -> [SKIP][78] ([i915#15657])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@gem_tiled_pread_basic@basic.html

  * igt@gem_unfence_active_buffers:
    - shard-dg1:          NOTRUN -> [SKIP][79] ([i915#4879])
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-12/igt@gem_unfence_active_buffers.html

  * igt@gem_userptr_blits@dmabuf-unsync:
    - shard-rkl:          NOTRUN -> [SKIP][80] ([i915#14544] / [i915#3297]) +1 other test skip
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_userptr_blits@dmabuf-unsync.html

  * igt@gem_userptr_blits@readonly-pwrite-unsync:
    - shard-dg2:          NOTRUN -> [SKIP][81] ([i915#3297])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@gem_userptr_blits@readonly-pwrite-unsync.html
    - shard-tglu:         NOTRUN -> [SKIP][82] ([i915#3297])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-6/igt@gem_userptr_blits@readonly-pwrite-unsync.html

  * igt@gem_userptr_blits@unsync-unmap-after-close:
    - shard-tglu-1:       NOTRUN -> [SKIP][83] ([i915#3297])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@gem_userptr_blits@unsync-unmap-after-close.html

  * igt@gem_userptr_blits@unsync-unmap-cycles:
    - shard-rkl:          NOTRUN -> [SKIP][84] ([i915#3297])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@gem_userptr_blits@unsync-unmap-cycles.html

  * igt@gem_workarounds@suspend-resume:
    - shard-glk11:        NOTRUN -> [INCOMPLETE][85] ([i915#13356] / [i915#14586])
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@gem_workarounds@suspend-resume.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-glk11:        NOTRUN -> [INCOMPLETE][86] ([i915#13356])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@gem_workarounds@suspend-resume-context.html

  * igt@gen7_exec_parse@basic-allocation:
    - shard-mtlp:         NOTRUN -> [SKIP][87] +7 other tests skip
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-2/igt@gen7_exec_parse@basic-allocation.html

  * igt@gen9_exec_parse@basic-rejected:
    - shard-tglu:         NOTRUN -> [SKIP][88] ([i915#2527] / [i915#2856]) +2 other tests skip
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-10/igt@gen9_exec_parse@basic-rejected.html
    - shard-mtlp:         NOTRUN -> [SKIP][89] ([i915#2856]) +2 other tests skip
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@gen9_exec_parse@basic-rejected.html

  * igt@gen9_exec_parse@shadow-peek:
    - shard-dg2:          NOTRUN -> [SKIP][90] ([i915#2856]) +2 other tests skip
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@gen9_exec_parse@shadow-peek.html
    - shard-rkl:          NOTRUN -> [SKIP][91] ([i915#2527]) +2 other tests skip
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@gen9_exec_parse@shadow-peek.html
    - shard-dg1:          NOTRUN -> [SKIP][92] ([i915#2527]) +1 other test skip
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@gen9_exec_parse@shadow-peek.html

  * igt@gen9_exec_parse@valid-registers:
    - shard-tglu-1:       NOTRUN -> [SKIP][93] ([i915#2527] / [i915#2856]) +2 other tests skip
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@gen9_exec_parse@valid-registers.html

  * igt@i915_drm_fdinfo@most-busy-idle-check-all@vecs1:
    - shard-dg2:          NOTRUN -> [SKIP][94] ([i915#14073]) +7 other tests skip
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@i915_drm_fdinfo@most-busy-idle-check-all@vecs1.html

  * igt@i915_fb_tiling@basic-x-tiling:
    - shard-dg1:          NOTRUN -> [SKIP][95] ([i915#13786])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@i915_fb_tiling@basic-x-tiling.html

  * igt@i915_module_load@fault-injection@__uc_init:
    - shard-tglu-1:       NOTRUN -> [SKIP][96] ([i915#15479]) +4 other tests skip
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@i915_module_load@fault-injection@__uc_init.html

  * igt@i915_module_load@fault-injection@i915_driver_mmio_probe:
    - shard-dg1:          NOTRUN -> [INCOMPLETE][97] ([i915#15481])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-14/igt@i915_module_load@fault-injection@i915_driver_mmio_probe.html

  * igt@i915_module_load@fault-injection@intel_connector_register:
    - shard-tglu-1:       NOTRUN -> [ABORT][98] ([i915#15342]) +1 other test abort
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@i915_module_load@fault-injection@intel_connector_register.html

  * igt@i915_pm_freq_api@freq-reset-multiple:
    - shard-rkl:          NOTRUN -> [SKIP][99] ([i915#8399])
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@i915_pm_freq_api@freq-reset-multiple.html

  * igt@i915_pm_freq_mult@media-freq@gt0:
    - shard-dg1:          NOTRUN -> [SKIP][100] ([i915#6590]) +1 other test skip
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@i915_pm_freq_mult@media-freq@gt0.html
    - shard-tglu:         NOTRUN -> [SKIP][101] ([i915#6590]) +1 other test skip
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-8/igt@i915_pm_freq_mult@media-freq@gt0.html

  * igt@i915_pm_freq_mult@media-freq@gt1:
    - shard-mtlp:         NOTRUN -> [SKIP][102] ([i915#6590]) +2 other tests skip
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@i915_pm_freq_mult@media-freq@gt1.html

  * igt@i915_pm_rps@min-max-config-loaded:
    - shard-dg2:          NOTRUN -> [SKIP][103] ([i915#11681] / [i915#6621])
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@i915_pm_rps@min-max-config-loaded.html

  * igt@i915_query@hwconfig_table:
    - shard-dg1:          NOTRUN -> [SKIP][104] ([i915#6245])
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@i915_query@hwconfig_table.html

  * igt@i915_query@test-query-geometry-subslices:
    - shard-rkl:          NOTRUN -> [SKIP][105] ([i915#5723])
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@i915_query@test-query-geometry-subslices.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-glk10:        NOTRUN -> [INCOMPLETE][106] ([i915#4817])
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk10/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_addfb_basic@framebuffer-vs-set-tiling:
    - shard-dg2:          NOTRUN -> [SKIP][107] ([i915#4212]) +2 other tests skip
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@kms_addfb_basic@framebuffer-vs-set-tiling.html
    - shard-dg1:          NOTRUN -> [SKIP][108] ([i915#4212]) +1 other test skip
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-12/igt@kms_addfb_basic@framebuffer-vs-set-tiling.html
    - shard-mtlp:         NOTRUN -> [SKIP][109] ([i915#4212]) +1 other test skip
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-8/igt@kms_addfb_basic@framebuffer-vs-set-tiling.html

  * igt@kms_addfb_basic@invalid-smem-bo-on-discrete:
    - shard-rkl:          NOTRUN -> [SKIP][110] ([i915#12454] / [i915#12712])
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_addfb_basic@invalid-smem-bo-on-discrete.html
    - shard-tglu:         NOTRUN -> [SKIP][111] ([i915#12454] / [i915#12712])
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@kms_addfb_basic@invalid-smem-bo-on-discrete.html

  * igt@kms_atomic_transition@plane-all-modeset-transition-fencing:
    - shard-mtlp:         NOTRUN -> [SKIP][112] ([i915#1769] / [i915#3555])
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@kms_atomic_transition@plane-all-modeset-transition-fencing.html

  * igt@kms_big_fb@4-tiled-16bpp-rotate-0:
    - shard-dg1:          NOTRUN -> [SKIP][113] ([i915#4538] / [i915#5286]) +1 other test skip
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@kms_big_fb@4-tiled-16bpp-rotate-0.html

  * igt@kms_big_fb@4-tiled-addfb:
    - shard-tglu-1:       NOTRUN -> [SKIP][114] ([i915#5286])
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_big_fb@4-tiled-addfb.html

  * igt@kms_big_fb@4-tiled-addfb-size-offset-overflow:
    - shard-tglu:         NOTRUN -> [SKIP][115] ([i915#5286]) +4 other tests skip
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-9/igt@kms_big_fb@4-tiled-addfb-size-offset-overflow.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip:
    - shard-rkl:          NOTRUN -> [SKIP][116] ([i915#5286]) +3 other tests skip
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip:
    - shard-mtlp:         [PASS][117] -> [FAIL][118] ([i915#15733] / [i915#5138])
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-5/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip.html

  * igt@kms_big_fb@linear-32bpp-rotate-90:
    - shard-rkl:          NOTRUN -> [SKIP][119] ([i915#14544] / [i915#3638])
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_big_fb@linear-32bpp-rotate-90.html

  * igt@kms_big_fb@linear-64bpp-rotate-90:
    - shard-rkl:          NOTRUN -> [SKIP][120] ([i915#3638]) +3 other tests skip
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_big_fb@linear-64bpp-rotate-90.html

  * igt@kms_big_fb@linear-max-hw-stride-64bpp-rotate-180-hflip:
    - shard-rkl:          NOTRUN -> [SKIP][121] ([i915#3828])
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@kms_big_fb@linear-max-hw-stride-64bpp-rotate-180-hflip.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][122] ([i915#3638])
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-12/igt@kms_big_fb@x-tiled-8bpp-rotate-90.html

  * igt@kms_big_fb@y-tiled-addfb-size-overflow:
    - shard-dg2:          NOTRUN -> [SKIP][123] ([i915#5190]) +1 other test skip
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_big_fb@y-tiled-addfb-size-overflow.html
    - shard-mtlp:         NOTRUN -> [SKIP][124] ([i915#6187])
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_big_fb@y-tiled-addfb-size-overflow.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-270:
    - shard-rkl:          NOTRUN -> [SKIP][125] +15 other tests skip
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_big_fb@yf-tiled-16bpp-rotate-270.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-90:
    - shard-dg2:          NOTRUN -> [SKIP][126] ([i915#4538] / [i915#5190]) +5 other tests skip
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html

  * igt@kms_big_fb@yf-tiled-64bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][127] ([i915#4538])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@kms_big_fb@yf-tiled-64bpp-rotate-90.html

  * igt@kms_ccs@bad-pixel-format-4-tiled-dg2-rc-ccs-cc@pipe-c-edp-1:
    - shard-mtlp:         NOTRUN -> [SKIP][128] ([i915#6095]) +14 other tests skip
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-2/igt@kms_ccs@bad-pixel-format-4-tiled-dg2-rc-ccs-cc@pipe-c-edp-1.html

  * igt@kms_ccs@bad-pixel-format-4-tiled-dg2-rc-ccs-cc@pipe-c-hdmi-a-1:
    - shard-glk11:        NOTRUN -> [SKIP][129] +66 other tests skip
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@kms_ccs@bad-pixel-format-4-tiled-dg2-rc-ccs-cc@pipe-c-hdmi-a-1.html

  * igt@kms_ccs@bad-rotation-90-4-tiled-dg2-mc-ccs@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][130] ([i915#6095]) +50 other tests skip
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-1/igt@kms_ccs@bad-rotation-90-4-tiled-dg2-mc-ccs@pipe-d-hdmi-a-3.html

  * igt@kms_ccs@bad-rotation-90-4-tiled-dg2-rc-ccs@pipe-c-hdmi-a-1:
    - shard-rkl:          NOTRUN -> [SKIP][131] ([i915#14098] / [i915#6095]) +43 other tests skip
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_ccs@bad-rotation-90-4-tiled-dg2-rc-ccs@pipe-c-hdmi-a-1.html

  * igt@kms_ccs@bad-rotation-90-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][132] ([i915#14544] / [i915#6095]) +16 other tests skip
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@bad-rotation-90-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc:
    - shard-tglu:         NOTRUN -> [SKIP][133] ([i915#6095]) +54 other tests skip
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_ccs@crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-lnl-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][134] ([i915#12313])
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@kms_ccs@crc-primary-rotation-180-4-tiled-lnl-ccs.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc@pipe-d-hdmi-a-1:
    - shard-dg2:          NOTRUN -> [SKIP][135] ([i915#10307] / [i915#10434] / [i915#6095])
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc@pipe-d-hdmi-a-1.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-1:
    - shard-tglu-1:       NOTRUN -> [SKIP][136] ([i915#6095]) +29 other tests skip
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-1.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][137] ([i915#6095]) +66 other tests skip
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_ccs@crc-primary-rotation-180-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2.html

  * igt@kms_ccs@crc-primary-suspend-4-tiled-lnl-ccs:
    - shard-tglu:         NOTRUN -> [SKIP][138] ([i915#12805])
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-8/igt@kms_ccs@crc-primary-suspend-4-tiled-lnl-ccs.html

  * igt@kms_ccs@crc-primary-suspend-y-tiled-gen12-rc-ccs-cc:
    - shard-rkl:          [PASS][139] -> [INCOMPLETE][140] ([i915#15582]) +3 other tests incomplete
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_ccs@crc-primary-suspend-y-tiled-gen12-rc-ccs-cc.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@crc-primary-suspend-y-tiled-gen12-rc-ccs-cc.html

  * igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs:
    - shard-glk:          NOTRUN -> [INCOMPLETE][141] ([i915#15582]) +1 other test incomplete
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk5/igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs.html

  * igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs@pipe-c-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][142] ([i915#14098] / [i915#14544] / [i915#6095]) +11 other tests skip
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs@pipe-c-hdmi-a-2.html

  * igt@kms_ccs@crc-sprite-planes-basic-4-tiled-mtl-mc-ccs@pipe-a-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][143] ([i915#10307] / [i915#6095]) +98 other tests skip
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-mtl-mc-ccs@pipe-a-hdmi-a-3.html

  * igt@kms_ccs@crc-sprite-planes-basic-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][144] ([i915#6095]) +192 other tests skip
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@kms_ccs@crc-sprite-planes-basic-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-4.html

  * igt@kms_ccs@random-ccs-data-4-tiled-bmg-ccs:
    - shard-tglu-1:       NOTRUN -> [SKIP][145] ([i915#12313])
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_ccs@random-ccs-data-4-tiled-bmg-ccs.html

  * igt@kms_ccs@random-ccs-data-4-tiled-lnl-ccs:
    - shard-dg1:          NOTRUN -> [SKIP][146] ([i915#12313])
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_ccs@random-ccs-data-4-tiled-lnl-ccs.html

  * igt@kms_cdclk@mode-transition:
    - shard-tglu-1:       NOTRUN -> [SKIP][147] ([i915#3742])
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_cdclk@mode-transition.html

  * igt@kms_cdclk@mode-transition@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][148] ([i915#13781]) +3 other tests skip
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_cdclk@mode-transition@pipe-d-hdmi-a-3.html

  * igt@kms_cdclk@plane-scaling:
    - shard-rkl:          NOTRUN -> [SKIP][149] ([i915#3742])
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_cdclk@plane-scaling.html

  * igt@kms_chamelium_audio@dp-audio:
    - shard-tglu:         NOTRUN -> [SKIP][150] ([i915#11151] / [i915#7828]) +10 other tests skip
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_chamelium_audio@dp-audio.html
    - shard-mtlp:         NOTRUN -> [SKIP][151] ([i915#11151] / [i915#7828]) +4 other tests skip
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@kms_chamelium_audio@dp-audio.html

  * igt@kms_chamelium_color@ctm-negative:
    - shard-dg2:          NOTRUN -> [SKIP][152] +4 other tests skip
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_chamelium_color@ctm-negative.html

  * igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k:
    - shard-tglu-1:       NOTRUN -> [SKIP][153] ([i915#11151] / [i915#7828]) +3 other tests skip
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k.html

  * igt@kms_chamelium_frames@hdmi-crc-multiple:
    - shard-dg2:          NOTRUN -> [SKIP][154] ([i915#11151] / [i915#7828]) +5 other tests skip
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@kms_chamelium_frames@hdmi-crc-multiple.html
    - shard-dg1:          NOTRUN -> [SKIP][155] ([i915#11151] / [i915#7828]) +5 other tests skip
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@kms_chamelium_frames@hdmi-crc-multiple.html

  * igt@kms_chamelium_frames@hdmi-crc-nonplanar-formats:
    - shard-rkl:          NOTRUN -> [SKIP][156] ([i915#11151] / [i915#14544] / [i915#7828]) +1 other test skip
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_chamelium_frames@hdmi-crc-nonplanar-formats.html

  * igt@kms_chamelium_hpd@dp-hpd-storm:
    - shard-rkl:          NOTRUN -> [SKIP][157] ([i915#11151] / [i915#7828]) +5 other tests skip
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_chamelium_hpd@dp-hpd-storm.html

  * igt@kms_content_protection@atomic:
    - shard-rkl:          NOTRUN -> [SKIP][158] ([i915#15865]) +1 other test skip
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_content_protection@atomic.html
    - shard-tglu:         NOTRUN -> [SKIP][159] ([i915#15865]) +1 other test skip
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@dp-mst-type-0-suspend-resume:
    - shard-tglu:         NOTRUN -> [SKIP][160] ([i915#15330])
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-9/igt@kms_content_protection@dp-mst-type-0-suspend-resume.html

  * igt@kms_content_protection@dp-mst-type-1-suspend-resume:
    - shard-mtlp:         NOTRUN -> [SKIP][161] ([i915#15330])
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@kms_content_protection@dp-mst-type-1-suspend-resume.html

  * igt@kms_content_protection@uevent:
    - shard-tglu-1:       NOTRUN -> [SKIP][162] ([i915#15865])
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_content_protection@uevent.html

  * igt@kms_cursor_crc@cursor-offscreen-32x10:
    - shard-rkl:          NOTRUN -> [SKIP][163] ([i915#3555]) +3 other tests skip
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_cursor_crc@cursor-offscreen-32x10.html
    - shard-dg1:          NOTRUN -> [SKIP][164] ([i915#3555]) +1 other test skip
   [164]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_cursor_crc@cursor-offscreen-32x10.html
    - shard-tglu:         NOTRUN -> [SKIP][165] ([i915#3555]) +2 other tests skip
   [165]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-5/igt@kms_cursor_crc@cursor-offscreen-32x10.html

  * igt@kms_cursor_crc@cursor-onscreen-128x42:
    - shard-rkl:          [PASS][166] -> [FAIL][167] ([i915#13566]) +2 other tests fail
   [166]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_cursor_crc@cursor-onscreen-128x42.html
   [167]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_cursor_crc@cursor-onscreen-128x42.html
    - shard-tglu:         [PASS][168] -> [FAIL][169] ([i915#13566]) +1 other test fail
   [168]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-9/igt@kms_cursor_crc@cursor-onscreen-128x42.html
   [169]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@kms_cursor_crc@cursor-onscreen-128x42.html

  * igt@kms_cursor_crc@cursor-onscreen-32x32:
    - shard-rkl:          NOTRUN -> [SKIP][170] ([i915#14544] / [i915#3555]) +1 other test skip
   [170]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_cursor_crc@cursor-onscreen-32x32.html

  * igt@kms_cursor_crc@cursor-onscreen-max-size:
    - shard-dg2:          NOTRUN -> [SKIP][171] ([i915#3555]) +2 other tests skip
   [171]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@kms_cursor_crc@cursor-onscreen-max-size.html
    - shard-tglu-1:       NOTRUN -> [SKIP][172] ([i915#3555])
   [172]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_cursor_crc@cursor-onscreen-max-size.html
    - shard-mtlp:         NOTRUN -> [SKIP][173] ([i915#3555] / [i915#8814]) +1 other test skip
   [173]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@kms_cursor_crc@cursor-onscreen-max-size.html

  * igt@kms_cursor_crc@cursor-random-256x85@pipe-a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [FAIL][174] ([i915#13566]) +1 other test fail
   [174]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_cursor_crc@cursor-random-256x85@pipe-a-hdmi-a-2.html

  * igt@kms_cursor_crc@cursor-sliding-512x512:
    - shard-rkl:          NOTRUN -> [SKIP][175] ([i915#13049])
   [175]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_cursor_crc@cursor-sliding-512x512.html
    - shard-tglu:         NOTRUN -> [SKIP][176] ([i915#13049]) +1 other test skip
   [176]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@kms_cursor_crc@cursor-sliding-512x512.html

  * igt@kms_cursor_legacy@cursorb-vs-flipa-varying-size:
    - shard-dg2:          NOTRUN -> [SKIP][177] ([i915#13046] / [i915#5354]) +1 other test skip
   [177]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_cursor_legacy@cursorb-vs-flipa-varying-size.html
    - shard-mtlp:         NOTRUN -> [SKIP][178] ([i915#9809]) +1 other test skip
   [178]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_cursor_legacy@cursorb-vs-flipa-varying-size.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-glk:          NOTRUN -> [FAIL][179] ([i915#15804])
   [179]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk1/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle:
    - shard-dg2:          NOTRUN -> [SKIP][180] ([i915#4103] / [i915#4213])
   [180]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle.html
    - shard-rkl:          NOTRUN -> [SKIP][181] ([i915#4103])
   [181]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle.html
    - shard-dg1:          NOTRUN -> [SKIP][182] ([i915#4103] / [i915#4213])
   [182]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-17/igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle.html
    - shard-tglu:         NOTRUN -> [SKIP][183] ([i915#4103])
   [183]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-7/igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle.html
    - shard-mtlp:         NOTRUN -> [SKIP][184] ([i915#4213])
   [184]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-2/igt@kms_cursor_legacy@short-busy-flip-before-cursor-toggle.html

  * igt@kms_dirtyfb@drrs-dirtyfb-ioctl:
    - shard-rkl:          NOTRUN -> [SKIP][185] ([i915#9723])
   [185]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_dirtyfb@drrs-dirtyfb-ioctl.html
    - shard-tglu:         NOTRUN -> [SKIP][186] ([i915#9723])
   [186]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@kms_dirtyfb@drrs-dirtyfb-ioctl.html

  * igt@kms_dp_link_training@non-uhbr-sst:
    - shard-rkl:          NOTRUN -> [SKIP][187] ([i915#13749])
   [187]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_dp_link_training@non-uhbr-sst.html
    - shard-tglu-1:       NOTRUN -> [SKIP][188] ([i915#13749])
   [188]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_dp_link_training@non-uhbr-sst.html

  * igt@kms_dsc@dsc-fractional-bpp:
    - shard-rkl:          NOTRUN -> [SKIP][189] ([i915#3840])
   [189]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_dsc@dsc-fractional-bpp.html

  * igt@kms_dsc@dsc-with-bpc:
    - shard-rkl:          NOTRUN -> [SKIP][190] ([i915#14544] / [i915#3555] / [i915#3840])
   [190]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_dsc@dsc-with-bpc.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-glk11:        NOTRUN -> [INCOMPLETE][191] ([i915#9878])
   [191]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@kms_fbcon_fbt@fbc-suspend.html
    - shard-rkl:          NOTRUN -> [ABORT][192] ([i915#15132])
   [192]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-1/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_feature_discovery@display-2x:
    - shard-rkl:          NOTRUN -> [SKIP][193] ([i915#1839])
   [193]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_feature_discovery@display-2x.html

  * igt@kms_feature_discovery@display-3x:
    - shard-tglu:         NOTRUN -> [SKIP][194] ([i915#1839]) +1 other test skip
   [194]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-5/igt@kms_feature_discovery@display-3x.html

  * igt@kms_flip@2x-absolute-wf_vblank:
    - shard-dg2:          NOTRUN -> [SKIP][195] ([i915#9934]) +1 other test skip
   [195]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_flip@2x-absolute-wf_vblank.html
    - shard-dg1:          NOTRUN -> [SKIP][196] ([i915#9934]) +1 other test skip
   [196]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_flip@2x-absolute-wf_vblank.html

  * igt@kms_flip@2x-dpms-vs-vblank-race-interruptible:
    - shard-mtlp:         NOTRUN -> [SKIP][197] ([i915#3637] / [i915#9934]) +1 other test skip
   [197]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@kms_flip@2x-dpms-vs-vblank-race-interruptible.html

  * igt@kms_flip@2x-flip-vs-dpms-on-nop:
    - shard-tglu:         NOTRUN -> [SKIP][198] ([i915#9934])
   [198]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_flip@2x-flip-vs-dpms-on-nop.html

  * igt@kms_flip@2x-flip-vs-suspend@ab-vga1-hdmi-a1:
    - shard-snb:          [PASS][199] -> [ABORT][200] ([i915#15840]) +1 other test abort
   [199]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-snb6/igt@kms_flip@2x-flip-vs-suspend@ab-vga1-hdmi-a1.html
   [200]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-snb4/igt@kms_flip@2x-flip-vs-suspend@ab-vga1-hdmi-a1.html

  * igt@kms_flip@2x-flip-vs-wf_vblank-interruptible:
    - shard-rkl:          NOTRUN -> [SKIP][201] ([i915#9934]) +7 other tests skip
   [201]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_flip@2x-flip-vs-wf_vblank-interruptible.html

  * igt@kms_flip@2x-plain-flip-fb-recreate:
    - shard-tglu-1:       NOTRUN -> [SKIP][202] ([i915#3637] / [i915#9934]) +1 other test skip
   [202]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_flip@2x-plain-flip-fb-recreate.html

  * igt@kms_flip@2x-plain-flip-interruptible:
    - shard-tglu:         NOTRUN -> [SKIP][203] ([i915#3637] / [i915#9934]) +5 other tests skip
   [203]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-8/igt@kms_flip@2x-plain-flip-interruptible.html

  * igt@kms_flip@2x-wf_vblank-ts-check-interruptible:
    - shard-rkl:          NOTRUN -> [SKIP][204] ([i915#14544] / [i915#9934])
   [204]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_flip@2x-wf_vblank-ts-check-interruptible.html

  * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling:
    - shard-dg2:          NOTRUN -> [SKIP][205] ([i915#15643]) +1 other test skip
   [205]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling.html
    - shard-rkl:          NOTRUN -> [SKIP][206] ([i915#15643]) +3 other tests skip
   [206]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling.html
    - shard-dg1:          NOTRUN -> [SKIP][207] ([i915#15643]) +2 other tests skip
   [207]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-17/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling.html

  * igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-downscaling:
    - shard-mtlp:         NOTRUN -> [SKIP][208] ([i915#15643]) +2 other tests skip
   [208]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-downscaling.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling:
    - shard-tglu:         NOTRUN -> [SKIP][209] ([i915#15643]) +2 other tests skip
   [209]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling.html

  * igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-downscaling:
    - shard-tglu-1:       NOTRUN -> [SKIP][210] ([i915#15643]) +2 other tests skip
   [210]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-downscaling.html

  * igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling:
    - shard-dg2:          NOTRUN -> [SKIP][211] ([i915#15643] / [i915#5190])
   [211]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-cpu:
    - shard-tglu-1:       NOTRUN -> [SKIP][212] +14 other tests skip
   [212]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-cpu.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-wc:
    - shard-mtlp:         NOTRUN -> [SKIP][213] ([i915#1825]) +15 other tests skip
   [213]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-8/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-move:
    - shard-tglu:         NOTRUN -> [SKIP][214] +54 other tests skip
   [214]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-4/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-move.html

  * igt@kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack-mmap-gtt:
    - shard-rkl:          NOTRUN -> [SKIP][215] ([i915#14544]) +2 other tests skip
   [215]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-glk:          NOTRUN -> [INCOMPLETE][216] ([i915#10056])
   [216]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk4/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbc-tiling-4:
    - shard-dg1:          NOTRUN -> [SKIP][217] ([i915#5439])
   [217]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@kms_frontbuffer_tracking@fbc-tiling-4.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-render:
    - shard-rkl:          NOTRUN -> [SKIP][218] ([i915#14544] / [i915#15102])
   [218]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-render.html
    - shard-dg1:          NOTRUN -> [SKIP][219] ([i915#15102]) +2 other tests skip
   [219]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-shrfb-draw-pwrite:
    - shard-rkl:          NOTRUN -> [SKIP][220] ([i915#15102]) +2 other tests skip
   [220]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-shrfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw:
    - shard-dg1:          NOTRUN -> [SKIP][221] ([i915#15102] / [i915#3458]) +6 other tests skip
   [221]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-13/igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][222] ([i915#15102] / [i915#3458]) +7 other tests skip
   [222]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-pwrite:
    - shard-dg1:          NOTRUN -> [SKIP][223] +17 other tests skip
   [223]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-fullscreen:
    - shard-glk10:        NOTRUN -> [SKIP][224] +49 other tests skip
   [224]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk10/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-fullscreen.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-blt:
    - shard-rkl:          NOTRUN -> [SKIP][225] ([i915#1825]) +34 other tests skip
   [225]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][226] ([i915#8708]) +3 other tests skip
   [226]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-render:
    - shard-tglu-1:       NOTRUN -> [SKIP][227] ([i915#15102]) +8 other tests skip
   [227]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-suspend:
    - shard-rkl:          NOTRUN -> [SKIP][228] ([i915#14544] / [i915#15102] / [i915#3023])
   [228]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-suspend.html

  * igt@kms_frontbuffer_tracking@psr-1p-offscreen-pri-indfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][229] ([i915#15102]) +2 other tests skip
   [229]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_frontbuffer_tracking@psr-1p-offscreen-pri-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt:
    - shard-rkl:          NOTRUN -> [SKIP][230] ([i915#15102] / [i915#3023]) +19 other tests skip
   [230]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-mmap-wc:
    - shard-dg2:          NOTRUN -> [SKIP][231] ([i915#8708]) +8 other tests skip
   [231]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-fullscreen:
    - shard-rkl:          NOTRUN -> [SKIP][232] ([i915#14544] / [i915#1825]) +2 other tests skip
   [232]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-fullscreen.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][233] ([i915#5354]) +7 other tests skip
   [233]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-1/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
    - shard-dg1:          NOTRUN -> [SKIP][234] ([i915#8708]) +8 other tests skip
   [234]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-shrfb-scaledprimary:
    - shard-tglu:         NOTRUN -> [SKIP][235] ([i915#15102]) +21 other tests skip
   [235]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_frontbuffer_tracking@psr-shrfb-scaledprimary.html

  * igt@kms_hdmi_inject@inject-audio:
    - shard-mtlp:         [PASS][236] -> [SKIP][237] ([i915#15725])
   [236]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-6/igt@kms_hdmi_inject@inject-audio.html
   [237]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@kms_hdmi_inject@inject-audio.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-dg2:          [PASS][238] -> [SKIP][239] ([i915#3555] / [i915#8228])
   [238]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@kms_hdr@bpc-switch-dpms.html
   [239]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_hdr@bpc-switch-dpms.html
    - shard-rkl:          NOTRUN -> [SKIP][240] ([i915#3555] / [i915#8228])
   [240]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@kms_hdr@bpc-switch-dpms.html
    - shard-tglu:         NOTRUN -> [SKIP][241] ([i915#3555] / [i915#8228])
   [241]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-7/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_hdr@static-toggle:
    - shard-dg2:          NOTRUN -> [SKIP][242] ([i915#3555] / [i915#8228])
   [242]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@kms_hdr@static-toggle.html

  * igt@kms_invalid_mode@clock-too-high:
    - shard-mtlp:         NOTRUN -> [SKIP][243] ([i915#3555] / [i915#6403] / [i915#8826])
   [243]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_invalid_mode@clock-too-high.html

  * igt@kms_invalid_mode@clock-too-high@pipe-c-edp-1:
    - shard-mtlp:         NOTRUN -> [SKIP][244] ([i915#9457]) +2 other tests skip
   [244]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_invalid_mode@clock-too-high@pipe-c-edp-1.html

  * igt@kms_invalid_mode@clock-too-high@pipe-d-edp-1:
    - shard-mtlp:         NOTRUN -> [SKIP][245] ([i915#8826] / [i915#9457])
   [245]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_invalid_mode@clock-too-high@pipe-d-edp-1.html

  * igt@kms_joiner@invalid-modeset-ultra-joiner:
    - shard-mtlp:         NOTRUN -> [SKIP][246] ([i915#15458])
   [246]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@kms_joiner@invalid-modeset-ultra-joiner.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-mtlp:         NOTRUN -> [SKIP][247] ([i915#15815])
   [247]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_pipe_crc_basic@suspend-read-crc:
    - shard-glk:          NOTRUN -> [INCOMPLETE][248] ([i915#12756] / [i915#13409] / [i915#13476])
   [248]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk2/igt@kms_pipe_crc_basic@suspend-read-crc.html

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-2:
    - shard-glk:          NOTRUN -> [INCOMPLETE][249] ([i915#13409] / [i915#13476])
   [249]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk2/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-2.html

  * igt@kms_plane@pixel-format-4-tiled-dg2-mc-ccs-modifier-source-clamping:
    - shard-tglu:         NOTRUN -> [SKIP][250] ([i915#15709]) +5 other tests skip
   [250]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@kms_plane@pixel-format-4-tiled-dg2-mc-ccs-modifier-source-clamping.html

  * igt@kms_plane@pixel-format-4-tiled-dg2-rc-ccs-modifier-source-clamping:
    - shard-dg2:          NOTRUN -> [SKIP][251] ([i915#15709]) +1 other test skip
   [251]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@kms_plane@pixel-format-4-tiled-dg2-rc-ccs-modifier-source-clamping.html
    - shard-mtlp:         NOTRUN -> [SKIP][252] ([i915#15709])
   [252]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-8/igt@kms_plane@pixel-format-4-tiled-dg2-rc-ccs-modifier-source-clamping.html

  * igt@kms_plane@pixel-format-4-tiled-mtl-rc-ccs-cc-modifier-source-clamping:
    - shard-dg1:          NOTRUN -> [SKIP][253] ([i915#15709]) +2 other tests skip
   [253]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@kms_plane@pixel-format-4-tiled-mtl-rc-ccs-cc-modifier-source-clamping.html

  * igt@kms_plane@pixel-format-y-tiled-gen12-mc-ccs-modifier:
    - shard-tglu-1:       NOTRUN -> [SKIP][254] ([i915#15709])
   [254]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_plane@pixel-format-y-tiled-gen12-mc-ccs-modifier.html

  * igt@kms_plane@pixel-format-yf-tiled-ccs-modifier:
    - shard-rkl:          NOTRUN -> [SKIP][255] ([i915#15709]) +4 other tests skip
   [255]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@kms_plane@pixel-format-yf-tiled-ccs-modifier.html

  * igt@kms_plane@pixel-format-yf-tiled-modifier:
    - shard-rkl:          NOTRUN -> [SKIP][256] ([i915#14544] / [i915#15709])
   [256]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_plane@pixel-format-yf-tiled-modifier.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a:
    - shard-glk:          [PASS][257] -> [INCOMPLETE][258] ([i915#13026])
   [257]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-glk5/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a.html
   [258]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk6/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a.html

  * igt@kms_plane_alpha_blend@constant-alpha-max:
    - shard-glk:          NOTRUN -> [FAIL][259] ([i915#10647] / [i915#12169])
   [259]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk9/igt@kms_plane_alpha_blend@constant-alpha-max.html

  * igt@kms_plane_alpha_blend@constant-alpha-max@pipe-c-hdmi-a-1:
    - shard-glk:          NOTRUN -> [FAIL][260] ([i915#10647]) +1 other test fail
   [260]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk9/igt@kms_plane_alpha_blend@constant-alpha-max@pipe-c-hdmi-a-1.html

  * igt@kms_plane_cursor@primary@pipe-a-edp-1-size-64:
    - shard-mtlp:         [PASS][261] -> [FAIL][262] ([i915#15733]) +3 other tests fail
   [261]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-5/igt@kms_plane_cursor@primary@pipe-a-edp-1-size-64.html
   [262]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-2/igt@kms_plane_cursor@primary@pipe-a-edp-1-size-64.html

  * igt@kms_plane_multiple@2x-tiling-none:
    - shard-rkl:          NOTRUN -> [SKIP][263] ([i915#13958])
   [263]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_plane_multiple@2x-tiling-none.html

  * igt@kms_plane_multiple@tiling-yf:
    - shard-rkl:          NOTRUN -> [SKIP][264] ([i915#14259])
   [264]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_plane_multiple@tiling-yf.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-c:
    - shard-tglu:         NOTRUN -> [SKIP][265] ([i915#15329]) +14 other tests skip
   [265]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-c.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-75-with-rotation@pipe-a:
    - shard-rkl:          NOTRUN -> [SKIP][266] ([i915#14544] / [i915#15329]) +3 other tests skip
   [266]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_plane_scaling@plane-downscale-factor-0-75-with-rotation@pipe-a.html
    - shard-dg1:          NOTRUN -> [SKIP][267] ([i915#15329]) +9 other tests skip
   [267]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-18/igt@kms_plane_scaling@plane-downscale-factor-0-75-with-rotation@pipe-a.html

  * igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-c:
    - shard-rkl:          NOTRUN -> [SKIP][268] ([i915#15329]) +7 other tests skip
   [268]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-c.html

  * igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75:
    - shard-mtlp:         NOTRUN -> [SKIP][269] ([i915#15329] / [i915#6953]) +1 other test skip
   [269]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75.html

  * igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75@pipe-d:
    - shard-mtlp:         NOTRUN -> [SKIP][270] ([i915#15329]) +12 other tests skip
   [270]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75@pipe-d.html

  * igt@kms_pm_backlight@brightness-with-dpms:
    - shard-dg1:          NOTRUN -> [SKIP][271] ([i915#12343])
   [271]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@kms_pm_backlight@brightness-with-dpms.html

  * igt@kms_pm_dc@dc6-dpms:
    - shard-dg2:          NOTRUN -> [SKIP][272] ([i915#15751])
   [272]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_pm_dc@dc6-dpms.html
    - shard-rkl:          NOTRUN -> [FAIL][273] ([i915#15752])
   [273]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_pm_dc@dc6-dpms.html
    - shard-dg1:          NOTRUN -> [SKIP][274] ([i915#3361])
   [274]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_pm_dc@dc6-dpms.html

  * igt@kms_pm_lpsp@screens-disabled:
    - shard-dg2:          NOTRUN -> [SKIP][275] ([i915#8430])
   [275]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@kms_pm_lpsp@screens-disabled.html
    - shard-rkl:          NOTRUN -> [SKIP][276] ([i915#8430])
   [276]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@kms_pm_lpsp@screens-disabled.html
    - shard-tglu-1:       NOTRUN -> [SKIP][277] ([i915#8430])
   [277]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_pm_lpsp@screens-disabled.html
    - shard-dg1:          NOTRUN -> [SKIP][278] ([i915#8430])
   [278]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-14/igt@kms_pm_lpsp@screens-disabled.html
    - shard-mtlp:         NOTRUN -> [SKIP][279] ([i915#8430])
   [279]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@kms_pm_lpsp@screens-disabled.html

  * igt@kms_pm_rpm@dpms-mode-unset-lpsp:
    - shard-rkl:          [PASS][280] -> [SKIP][281] ([i915#14544] / [i915#15073])
   [280]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_pm_rpm@dpms-mode-unset-lpsp.html
   [281]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_pm_rpm@dpms-mode-unset-lpsp.html

  * igt@kms_pm_rpm@modeset-lpsp:
    - shard-dg2:          NOTRUN -> [SKIP][282] ([i915#15073]) +1 other test skip
   [282]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_pm_rpm@modeset-lpsp.html

  * igt@kms_pm_rpm@modeset-lpsp-stress-no-wait:
    - shard-rkl:          NOTRUN -> [SKIP][283] ([i915#15073]) +1 other test skip
   [283]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_pm_rpm@modeset-lpsp-stress-no-wait.html

  * igt@kms_pm_rpm@modeset-non-lpsp:
    - shard-dg1:          [PASS][284] -> [SKIP][285] ([i915#15073]) +2 other tests skip
   [284]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-19/igt@kms_pm_rpm@modeset-non-lpsp.html
   [285]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_pm_rpm@modeset-non-lpsp.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress:
    - shard-rkl:          [PASS][286] -> [SKIP][287] ([i915#15073])
   [286]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-4/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
   [287]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
    - shard-mtlp:         NOTRUN -> [SKIP][288] ([i915#15073])
   [288]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-8/igt@kms_pm_rpm@modeset-non-lpsp-stress.html

  * igt@kms_pm_rpm@system-suspend-idle:
    - shard-rkl:          [PASS][289] -> [INCOMPLETE][290] ([i915#14419])
   [289]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@kms_pm_rpm@system-suspend-idle.html
   [290]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_pm_rpm@system-suspend-idle.html

  * igt@kms_psr2_sf@fbc-psr2-cursor-plane-move-continuous-exceed-sf:
    - shard-glk10:        NOTRUN -> [SKIP][291] ([i915#11520]) +1 other test skip
   [291]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk10/igt@kms_psr2_sf@fbc-psr2-cursor-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_sf@fbc-psr2-primary-plane-update-sf-dmg-area:
    - shard-glk:          NOTRUN -> [SKIP][292] ([i915#11520]) +16 other tests skip
   [292]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk6/igt@kms_psr2_sf@fbc-psr2-primary-plane-update-sf-dmg-area.html

  * igt@kms_psr2_sf@pr-overlay-primary-update-sf-dmg-area:
    - shard-tglu:         NOTRUN -> [SKIP][293] ([i915#11520]) +7 other tests skip
   [293]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@kms_psr2_sf@pr-overlay-primary-update-sf-dmg-area.html

  * igt@kms_psr2_sf@pr-plane-move-sf-dmg-area:
    - shard-mtlp:         NOTRUN -> [SKIP][294] ([i915#12316]) +1 other test skip
   [294]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-4/igt@kms_psr2_sf@pr-plane-move-sf-dmg-area.html
    - shard-rkl:          NOTRUN -> [SKIP][295] ([i915#11520] / [i915#14544])
   [295]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_psr2_sf@pr-plane-move-sf-dmg-area.html

  * igt@kms_psr2_sf@pr-primary-plane-update-sf-dmg-area:
    - shard-glk11:        NOTRUN -> [SKIP][296] ([i915#11520]) +1 other test skip
   [296]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk11/igt@kms_psr2_sf@pr-primary-plane-update-sf-dmg-area.html

  * igt@kms_psr2_sf@pr-primary-plane-update-sf-dmg-area-big-fb:
    - shard-tglu-1:       NOTRUN -> [SKIP][297] ([i915#11520]) +2 other tests skip
   [297]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_psr2_sf@pr-primary-plane-update-sf-dmg-area-big-fb.html

  * igt@kms_psr2_sf@psr2-overlay-plane-update-continuous-sf:
    - shard-dg2:          NOTRUN -> [SKIP][298] ([i915#11520]) +4 other tests skip
   [298]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@kms_psr2_sf@psr2-overlay-plane-update-continuous-sf.html
    - shard-rkl:          NOTRUN -> [SKIP][299] ([i915#11520]) +7 other tests skip
   [299]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_psr2_sf@psr2-overlay-plane-update-continuous-sf.html

  * igt@kms_psr2_sf@psr2-primary-plane-update-sf-dmg-area-big-fb:
    - shard-snb:          NOTRUN -> [SKIP][300] ([i915#11520]) +2 other tests skip
   [300]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-snb5/igt@kms_psr2_sf@psr2-primary-plane-update-sf-dmg-area-big-fb.html
    - shard-dg1:          NOTRUN -> [SKIP][301] ([i915#11520]) +3 other tests skip
   [301]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-19/igt@kms_psr2_sf@psr2-primary-plane-update-sf-dmg-area-big-fb.html

  * igt@kms_psr@fbc-psr-cursor-plane-move:
    - shard-rkl:          NOTRUN -> [SKIP][302] ([i915#1072] / [i915#9732]) +14 other tests skip
   [302]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_psr@fbc-psr-cursor-plane-move.html
    - shard-dg1:          NOTRUN -> [SKIP][303] ([i915#1072] / [i915#9732]) +10 other tests skip
   [303]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-17/igt@kms_psr@fbc-psr-cursor-plane-move.html

  * igt@kms_psr@fbc-psr-no-drrs:
    - shard-tglu:         NOTRUN -> [SKIP][304] ([i915#9732]) +19 other tests skip
   [304]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-8/igt@kms_psr@fbc-psr-no-drrs.html

  * igt@kms_psr@fbc-psr2-cursor-mmap-gtt:
    - shard-glk:          NOTRUN -> [SKIP][305] +490 other tests skip
   [305]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk8/igt@kms_psr@fbc-psr2-cursor-mmap-gtt.html

  * igt@kms_psr@fbc-psr2-primary-mmap-cpu:
    - shard-mtlp:         NOTRUN -> [SKIP][306] ([i915#9688]) +8 other tests skip
   [306]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@kms_psr@fbc-psr2-primary-mmap-cpu.html

  * igt@kms_psr@pr-sprite-plane-onoff:
    - shard-tglu-1:       NOTRUN -> [SKIP][307] ([i915#9732]) +5 other tests skip
   [307]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_psr@pr-sprite-plane-onoff.html

  * igt@kms_psr@psr-suspend:
    - shard-dg2:          NOTRUN -> [SKIP][308] ([i915#1072] / [i915#9732]) +9 other tests skip
   [308]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_psr@psr-suspend.html

  * igt@kms_psr@psr2-cursor-render:
    - shard-rkl:          NOTRUN -> [SKIP][309] ([i915#1072] / [i915#14544] / [i915#9732]) +2 other tests skip
   [309]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_psr@psr2-cursor-render.html

  * igt@kms_rotation_crc@primary-rotation-90:
    - shard-mtlp:         NOTRUN -> [SKIP][310] ([i915#12755] / [i915#15867])
   [310]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_rotation_crc@primary-rotation-90.html
    - shard-dg2:          NOTRUN -> [SKIP][311] ([i915#12755] / [i915#15867])
   [311]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-8/igt@kms_rotation_crc@primary-rotation-90.html

  * igt@kms_rotation_crc@primary-yf-tiled-reflect-x-0:
    - shard-tglu-1:       NOTRUN -> [SKIP][312] ([i915#5289])
   [312]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-1/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-0.html

  * igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90:
    - shard-rkl:          NOTRUN -> [SKIP][313] ([i915#5289]) +1 other test skip
   [313]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90.html
    - shard-tglu:         NOTRUN -> [SKIP][314] ([i915#5289]) +1 other test skip
   [314]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-10/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90.html

  * igt@kms_setmode@invalid-clone-exclusive-crtc:
    - shard-mtlp:         NOTRUN -> [SKIP][315] ([i915#3555] / [i915#8809] / [i915#8823])
   [315]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@kms_setmode@invalid-clone-exclusive-crtc.html

  * igt@kms_vblank@ts-continuation-dpms-suspend@pipe-a-hdmi-a-1:
    - shard-glk:          NOTRUN -> [INCOMPLETE][316] ([i915#12276]) +3 other tests incomplete
   [316]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk8/igt@kms_vblank@ts-continuation-dpms-suspend@pipe-a-hdmi-a-1.html

  * igt@kms_vrr@lobf:
    - shard-rkl:          NOTRUN -> [SKIP][317] ([i915#11920])
   [317]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_vrr@lobf.html
    - shard-tglu:         NOTRUN -> [SKIP][318] ([i915#11920])
   [318]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-10/igt@kms_vrr@lobf.html

  * igt@perf_pmu@busy-double-start:
    - shard-mtlp:         NOTRUN -> [FAIL][319] ([i915#4349]) +2 other tests fail
   [319]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@perf_pmu@busy-double-start.html

  * igt@perf_pmu@module-unload:
    - shard-mtlp:         NOTRUN -> [ABORT][320] ([i915#15778])
   [320]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-7/igt@perf_pmu@module-unload.html

  * igt@perf_pmu@rc6-suspend:
    - shard-glk:          NOTRUN -> [INCOMPLETE][321] ([i915#13356])
   [321]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk8/igt@perf_pmu@rc6-suspend.html
    - shard-dg2:          [PASS][322] -> [ABORT][323] ([i915#15131])
   [322]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-6/igt@perf_pmu@rc6-suspend.html
   [323]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-10/igt@perf_pmu@rc6-suspend.html

  * igt@prime_vgem@basic-fence-flip:
    - shard-dg1:          NOTRUN -> [SKIP][324] ([i915#3708])
   [324]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@prime_vgem@basic-fence-flip.html
    - shard-dg2:          NOTRUN -> [SKIP][325] ([i915#3708])
   [325]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-3/igt@prime_vgem@basic-fence-flip.html

  * igt@prime_vgem@coherency-gtt:
    - shard-rkl:          NOTRUN -> [SKIP][326] ([i915#3708])
   [326]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@prime_vgem@coherency-gtt.html

  * igt@sriov_basic@enable-vfs-autoprobe-off@numvfs-6:
    - shard-tglu:         NOTRUN -> [FAIL][327] ([i915#12910]) +9 other tests fail
   [327]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-2/igt@sriov_basic@enable-vfs-autoprobe-off@numvfs-6.html

  * igt@tools_test@sysfs_l3_parity:
    - shard-dg2:          NOTRUN -> [SKIP][328] ([i915#4818])
   [328]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-1/igt@tools_test@sysfs_l3_parity.html

  
#### Possible fixes ####

  * igt@gem_exec_big@single:
    - shard-mtlp:         [FAIL][329] -> [PASS][330]
   [329]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-3/igt@gem_exec_big@single.html
   [330]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@gem_exec_big@single.html

  * igt@gem_softpin@noreloc-s3:
    - shard-dg2:          [ABORT][331] ([i915#15131]) -> [PASS][332]
   [331]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@gem_softpin@noreloc-s3.html
   [332]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@gem_softpin@noreloc-s3.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-rkl:          [ABORT][333] ([i915#15131]) -> [PASS][334]
   [333]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-1/igt@gem_workarounds@suspend-resume-context.html
   [334]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@gem_workarounds@suspend-resume-context.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-glk:          [INCOMPLETE][335] ([i915#13356] / [i915#14586]) -> [PASS][336]
   [335]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-glk8/igt@gem_workarounds@suspend-resume-fd.html
   [336]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk6/igt@gem_workarounds@suspend-resume-fd.html

  * igt@i915_suspend@basic-s3-without-i915:
    - shard-glk:          [INCOMPLETE][337] ([i915#4817]) -> [PASS][338]
   [337]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-glk5/igt@i915_suspend@basic-s3-without-i915.html
   [338]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk9/igt@i915_suspend@basic-s3-without-i915.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-rkl:          [ABORT][339] ([i915#15140]) -> [PASS][340]
   [339]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-1/igt@i915_suspend@fence-restore-tiled2untiled.html
   [340]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-rkl:          [INCOMPLETE][341] ([i915#4817]) -> [PASS][342] +1 other test pass
   [341]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@i915_suspend@fence-restore-untiled.html
   [342]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_atomic_transition@plane-all-modeset-transition:
    - shard-dg2:          [FAIL][343] ([i915#5956]) -> [PASS][344]
   [343]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-1/igt@kms_atomic_transition@plane-all-modeset-transition.html
   [344]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@kms_atomic_transition@plane-all-modeset-transition.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip:
    - shard-mtlp:         [FAIL][345] ([i915#15733] / [i915#5138]) -> [PASS][346]
   [345]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-6/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip.html
   [346]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-6/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip.html

  * igt@kms_cursor_crc@cursor-sliding-128x42:
    - shard-rkl:          [FAIL][347] ([i915#13566]) -> [PASS][348] +1 other test pass
   [347]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@kms_cursor_crc@cursor-sliding-128x42.html
   [348]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_cursor_crc@cursor-sliding-128x42.html

  * igt@kms_cursor_crc@cursor-sliding-128x42@pipe-a-hdmi-a-1:
    - shard-tglu:         [FAIL][349] ([i915#13566]) -> [PASS][350] +3 other tests pass
   [349]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-3/igt@kms_cursor_crc@cursor-sliding-128x42@pipe-a-hdmi-a-1.html
   [350]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-9/igt@kms_cursor_crc@cursor-sliding-128x42@pipe-a-hdmi-a-1.html

  * igt@kms_hdr@invalid-metadata-sizes:
    - shard-rkl:          [SKIP][351] ([i915#3555] / [i915#8228]) -> [PASS][352]
   [351]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_hdr@invalid-metadata-sizes.html
   [352]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_hdr@invalid-metadata-sizes.html

  * igt@kms_invalid_mode@bad-vsync-start:
    - shard-dg1:          [DMESG-WARN][353] ([i915#4423]) -> [PASS][354]
   [353]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-18/igt@kms_invalid_mode@bad-vsync-start.html
   [354]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-12/igt@kms_invalid_mode@bad-vsync-start.html

  * igt@kms_pipe_crc_basic@suspend-read-crc:
    - shard-rkl:          [INCOMPLETE][355] ([i915#12756] / [i915#13476]) -> [PASS][356]
   [355]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_pipe_crc_basic@suspend-read-crc.html
   [356]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_pipe_crc_basic@suspend-read-crc.html

  * igt@kms_plane_cursor@viewport:
    - shard-mtlp:         [DMESG-WARN][357] -> [PASS][358] +1 other test pass
   [357]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-5/igt@kms_plane_cursor@viewport.html
   [358]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-3/igt@kms_plane_cursor@viewport.html

  * igt@kms_pm_rpm@modeset-non-lpsp:
    - shard-dg2:          [SKIP][359] ([i915#15073]) -> [PASS][360]
   [359]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-4/igt@kms_pm_rpm@modeset-non-lpsp.html
   [360]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_pm_rpm@modeset-non-lpsp.html
    - shard-rkl:          [SKIP][361] ([i915#15073]) -> [PASS][362] +1 other test pass
   [361]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_pm_rpm@modeset-non-lpsp.html
   [362]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_pm_rpm@modeset-non-lpsp.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress:
    - shard-dg1:          [SKIP][363] ([i915#15073]) -> [PASS][364]
   [363]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-15/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
   [364]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-12/igt@kms_pm_rpm@modeset-non-lpsp-stress.html

  * igt@kms_setmode@basic:
    - shard-tglu:         [FAIL][365] ([i915#15106]) -> [PASS][366] +2 other tests pass
   [365]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-2/igt@kms_setmode@basic.html
   [366]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-6/igt@kms_setmode@basic.html

  * igt@sysfs_preempt_timeout@timeout:
    - shard-dg2:          [ABORT][367] -> [PASS][368] +1 other test pass
   [367]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@sysfs_preempt_timeout@timeout.html
   [368]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@sysfs_preempt_timeout@timeout.html

  
#### Warnings ####

  * igt@drm_buddy@drm_buddy:
    - shard-rkl:          [SKIP][369] ([i915#14544] / [i915#15678]) -> [SKIP][370] ([i915#15678])
   [369]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@drm_buddy@drm_buddy.html
   [370]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@drm_buddy@drm_buddy.html

  * igt@gem_close_race@multigpu-basic-process:
    - shard-rkl:          [SKIP][371] ([i915#14544] / [i915#7697]) -> [SKIP][372] ([i915#7697])
   [371]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@gem_close_race@multigpu-basic-process.html
   [372]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@gem_close_race@multigpu-basic-process.html

  * igt@gem_exec_capture@capture-recoverable:
    - shard-rkl:          [SKIP][373] ([i915#6344]) -> [SKIP][374] ([i915#14544] / [i915#6344])
   [373]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@gem_exec_capture@capture-recoverable.html
   [374]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_exec_capture@capture-recoverable.html

  * igt@gem_exec_reloc@basic-gtt-cpu:
    - shard-rkl:          [SKIP][375] ([i915#14544] / [i915#3281]) -> [SKIP][376] ([i915#3281]) +2 other tests skip
   [375]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@gem_exec_reloc@basic-gtt-cpu.html
   [376]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@gem_exec_reloc@basic-gtt-cpu.html

  * igt@gem_exec_reloc@basic-gtt-wc-noreloc:
    - shard-rkl:          [SKIP][377] ([i915#3281]) -> [SKIP][378] ([i915#14544] / [i915#3281]) +4 other tests skip
   [377]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@gem_exec_reloc@basic-gtt-wc-noreloc.html
   [378]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_exec_reloc@basic-gtt-wc-noreloc.html

  * igt@gem_huc_copy@huc-copy:
    - shard-rkl:          [SKIP][379] ([i915#2190]) -> [SKIP][380] ([i915#14544] / [i915#2190])
   [379]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@gem_huc_copy@huc-copy.html
   [380]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_huc_copy@huc-copy.html

  * igt@gem_pwrite@basic-self:
    - shard-rkl:          [SKIP][381] ([i915#3282]) -> [SKIP][382] ([i915#14544] / [i915#3282]) +2 other tests skip
   [381]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@gem_pwrite@basic-self.html
   [382]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_pwrite@basic-self.html

  * igt@gem_pxp@hw-rejects-pxp-context:
    - shard-rkl:          [SKIP][383] ([i915#13717] / [i915#14544]) -> [SKIP][384] ([i915#13717])
   [383]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@gem_pxp@hw-rejects-pxp-context.html
   [384]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@gem_pxp@hw-rejects-pxp-context.html

  * igt@gem_set_tiling_vs_blt@tiled-to-tiled:
    - shard-rkl:          [SKIP][385] ([i915#8411]) -> [SKIP][386] ([i915#14544] / [i915#8411])
   [385]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-4/igt@gem_set_tiling_vs_blt@tiled-to-tiled.html
   [386]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_set_tiling_vs_blt@tiled-to-tiled.html

  * igt@gem_userptr_blits@coherency-sync:
    - shard-rkl:          [SKIP][387] ([i915#3297]) -> [SKIP][388] ([i915#14544] / [i915#3297]) +1 other test skip
   [387]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@gem_userptr_blits@coherency-sync.html
   [388]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gem_userptr_blits@coherency-sync.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-rkl:          [SKIP][389] ([i915#2527]) -> [SKIP][390] ([i915#14544] / [i915#2527])
   [389]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@gen9_exec_parse@allowed-all.html
   [390]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_module_load@fault-injection:
    - shard-dg1:          [ABORT][391] -> [ABORT][392] ([i915#15481]) +1 other test abort
   [391]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-14/igt@i915_module_load@fault-injection.html
   [392]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-14/igt@i915_module_load@fault-injection.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-rkl:          [SKIP][393] ([i915#14498] / [i915#14544]) -> [SKIP][394] ([i915#14498])
   [393]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@i915_pm_rc6_residency@rc6-idle.html
   [394]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@kms_big_fb@4-tiled-16bpp-rotate-0:
    - shard-rkl:          [SKIP][395] ([i915#5286]) -> [SKIP][396] ([i915#14544] / [i915#5286]) +2 other tests skip
   [395]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_big_fb@4-tiled-16bpp-rotate-0.html
   [396]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_big_fb@4-tiled-16bpp-rotate-0.html

  * igt@kms_big_fb@4-tiled-32bpp-rotate-0:
    - shard-rkl:          [SKIP][397] ([i915#14544] / [i915#5286]) -> [SKIP][398] ([i915#5286]) +1 other test skip
   [397]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_big_fb@4-tiled-32bpp-rotate-0.html
   [398]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-3/igt@kms_big_fb@4-tiled-32bpp-rotate-0.html

  * igt@kms_big_fb@linear-64bpp-rotate-270:
    - shard-rkl:          [SKIP][399] ([i915#3638]) -> [SKIP][400] ([i915#14544] / [i915#3638]) +1 other test skip
   [399]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_big_fb@linear-64bpp-rotate-270.html
   [400]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_big_fb@linear-64bpp-rotate-270.html

  * igt@kms_big_fb@linear-max-hw-stride-32bpp-rotate-0-hflip:
    - shard-rkl:          [SKIP][401] ([i915#14544] / [i915#3828]) -> [SKIP][402] ([i915#3828])
   [401]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_big_fb@linear-max-hw-stride-32bpp-rotate-0-hflip.html
   [402]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@kms_big_fb@linear-max-hw-stride-32bpp-rotate-0-hflip.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180:
    - shard-rkl:          [SKIP][403] -> [SKIP][404] ([i915#14544]) +5 other tests skip
   [403]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180.html
   [404]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-bmg-ccs:
    - shard-rkl:          [SKIP][405] ([i915#12313]) -> [SKIP][406] ([i915#12313] / [i915#14544])
   [405]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_ccs@crc-primary-rotation-180-4-tiled-bmg-ccs.html
   [406]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@crc-primary-rotation-180-4-tiled-bmg-ccs.html

  * igt@kms_ccs@crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc@pipe-a-hdmi-a-2:
    - shard-rkl:          [SKIP][407] ([i915#14544] / [i915#6095]) -> [SKIP][408] ([i915#6095]) +1 other test skip
   [407]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_ccs@crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc@pipe-a-hdmi-a-2.html
   [408]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_ccs@crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc@pipe-a-hdmi-a-2.html

  * igt@kms_ccs@crc-primary-suspend-4-tiled-dg2-rc-ccs:
    - shard-rkl:          [SKIP][409] ([i915#14098] / [i915#14544] / [i915#6095]) -> [SKIP][410] ([i915#14098] / [i915#6095]) +6 other tests skip
   [409]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_ccs@crc-primary-suspend-4-tiled-dg2-rc-ccs.html
   [410]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_ccs@crc-primary-suspend-4-tiled-dg2-rc-ccs.html

  * igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs:
    - shard-rkl:          [SKIP][411] ([i915#14098] / [i915#6095]) -> [SKIP][412] ([i915#14098] / [i915#14544] / [i915#6095]) +11 other tests skip
   [411]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs.html
   [412]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@crc-primary-suspend-yf-tiled-ccs.html

  * igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs:
    - shard-dg1:          [SKIP][413] ([i915#4423] / [i915#6095]) -> [SKIP][414] ([i915#6095]) +1 other test skip
   [413]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-17/igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs.html
   [414]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-16/igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs.html

  * igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2:
    - shard-rkl:          [SKIP][415] ([i915#6095]) -> [SKIP][416] ([i915#14544] / [i915#6095]) +5 other tests skip
   [415]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2.html
   [416]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_ccs@random-ccs-data-4-tiled-mtl-rc-ccs@pipe-b-hdmi-a-2.html

  * igt@kms_chamelium_frames@hdmi-crc-fast:
    - shard-rkl:          [SKIP][417] ([i915#11151] / [i915#14544] / [i915#7828]) -> [SKIP][418] ([i915#11151] / [i915#7828]) +4 other tests skip
   [417]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_chamelium_frames@hdmi-crc-fast.html
   [418]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@kms_chamelium_frames@hdmi-crc-fast.html

  * igt@kms_chamelium_hpd@vga-hpd-with-enabled-mode:
    - shard-rkl:          [SKIP][419] ([i915#11151] / [i915#7828]) -> [SKIP][420] ([i915#11151] / [i915#14544] / [i915#7828]) +1 other test skip
   [419]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@kms_chamelium_hpd@vga-hpd-with-enabled-mode.html
   [420]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_chamelium_hpd@vga-hpd-with-enabled-mode.html

  * igt@kms_content_protection@dp-mst-type-1:
    - shard-rkl:          [SKIP][421] ([i915#15330] / [i915#3116]) -> [SKIP][422] ([i915#14544] / [i915#15330] / [i915#3116])
   [421]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_content_protection@dp-mst-type-1.html
   [422]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_content_protection@dp-mst-type-1.html

  * igt@kms_content_protection@lic-type-0:
    - shard-dg2:          [FAIL][423] ([i915#7173]) -> [SKIP][424] ([i915#15865])
   [423]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@kms_content_protection@lic-type-0.html
   [424]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-7/igt@kms_content_protection@lic-type-0.html
    - shard-rkl:          [SKIP][425] ([i915#15865]) -> [SKIP][426] ([i915#14544] / [i915#15865])
   [425]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_content_protection@lic-type-0.html
   [426]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_content_protection@lic-type-0.html

  * igt@kms_content_protection@mei-interface:
    - shard-dg1:          [SKIP][427] ([i915#15865]) -> [SKIP][428] ([i915#9433])
   [427]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-19/igt@kms_content_protection@mei-interface.html
   [428]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-13/igt@kms_content_protection@mei-interface.html

  * igt@kms_cursor_crc@cursor-onscreen-512x170:
    - shard-rkl:          [SKIP][429] ([i915#13049]) -> [SKIP][430] ([i915#13049] / [i915#14544])
   [429]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-4/igt@kms_cursor_crc@cursor-onscreen-512x170.html
   [430]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_cursor_crc@cursor-onscreen-512x170.html

  * igt@kms_cursor_crc@cursor-sliding-512x170:
    - shard-dg2:          [SKIP][431] ([i915#13049] / [i915#3359]) -> [SKIP][432] ([i915#13049])
   [431]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@kms_cursor_crc@cursor-sliding-512x170.html
   [432]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-1/igt@kms_cursor_crc@cursor-sliding-512x170.html
    - shard-rkl:          [SKIP][433] ([i915#13049] / [i915#14544]) -> [SKIP][434] ([i915#13049])
   [433]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_cursor_crc@cursor-sliding-512x170.html
   [434]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_cursor_crc@cursor-sliding-512x170.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-legacy:
    - shard-rkl:          [SKIP][435] ([i915#14544]) -> [SKIP][436] +6 other tests skip
   [435]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_cursor_legacy@cursora-vs-flipb-legacy.html
   [436]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_cursor_legacy@cursora-vs-flipb-legacy.html

  * igt@kms_dp_linktrain_fallback@dp-fallback:
    - shard-rkl:          [SKIP][437] ([i915#13707]) -> [SKIP][438] ([i915#13707] / [i915#14544])
   [437]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_dp_linktrain_fallback@dp-fallback.html
   [438]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_dp_linktrain_fallback@dp-fallback.html

  * igt@kms_dp_linktrain_fallback@dsc-fallback:
    - shard-rkl:          [SKIP][439] ([i915#13707] / [i915#14544]) -> [SKIP][440] ([i915#13707])
   [439]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_dp_linktrain_fallback@dsc-fallback.html
   [440]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_dp_linktrain_fallback@dsc-fallback.html

  * igt@kms_dsc@dsc-with-output-formats:
    - shard-rkl:          [SKIP][441] ([i915#14544] / [i915#3555] / [i915#3840]) -> [SKIP][442] ([i915#3555] / [i915#3840])
   [441]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_dsc@dsc-with-output-formats.html
   [442]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_dsc@dsc-with-output-formats.html

  * igt@kms_feature_discovery@display-3x:
    - shard-rkl:          [SKIP][443] ([i915#14544] / [i915#1839]) -> [SKIP][444] ([i915#1839])
   [443]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_feature_discovery@display-3x.html
   [444]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@kms_feature_discovery@display-3x.html

  * igt@kms_feature_discovery@psr2:
    - shard-rkl:          [SKIP][445] ([i915#658]) -> [SKIP][446] ([i915#14544] / [i915#658])
   [445]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_feature_discovery@psr2.html
   [446]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_feature_discovery@psr2.html

  * igt@kms_flip@2x-flip-vs-modeset:
    - shard-rkl:          [SKIP][447] ([i915#14544] / [i915#9934]) -> [SKIP][448] ([i915#9934]) +2 other tests skip
   [447]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_flip@2x-flip-vs-modeset.html
   [448]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_flip@2x-flip-vs-modeset.html

  * igt@kms_flip@2x-single-buffer-flip-vs-dpms-off-vs-modeset:
    - shard-rkl:          [SKIP][449] ([i915#9934]) -> [SKIP][450] ([i915#14544] / [i915#9934]) +3 other tests skip
   [449]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_flip@2x-single-buffer-flip-vs-dpms-off-vs-modeset.html
   [450]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_flip@2x-single-buffer-flip-vs-dpms-off-vs-modeset.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-glk:          [INCOMPLETE][451] ([i915#12745] / [i915#4839] / [i915#6113]) -> [INCOMPLETE][452] ([i915#12745] / [i915#4839])
   [451]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-glk1/igt@kms_flip@flip-vs-suspend.html
   [452]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk4/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@flip-vs-suspend@a-hdmi-a1:
    - shard-glk:          [INCOMPLETE][453] ([i915#12745] / [i915#6113]) -> [INCOMPLETE][454] ([i915#12745])
   [453]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-glk1/igt@kms_flip@flip-vs-suspend@a-hdmi-a1.html
   [454]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-glk4/igt@kms_flip@flip-vs-suspend@a-hdmi-a1.html

  * igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-upscaling:
    - shard-dg1:          [SKIP][455] ([i915#15643] / [i915#4423]) -> [SKIP][456] ([i915#15643]) +1 other test skip
   [455]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-17/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-upscaling.html
   [456]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-15/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-upscaling.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling:
    - shard-rkl:          [SKIP][457] ([i915#15643]) -> [SKIP][458] ([i915#14544] / [i915#15643])
   [457]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling.html
   [458]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-downscaling:
    - shard-rkl:          [SKIP][459] ([i915#14544] / [i915#15643]) -> [SKIP][460] ([i915#15643])
   [459]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-downscaling.html
   [460]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-5/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-downscaling.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-mtlp:         [SKIP][461] ([i915#15672]) -> [SKIP][462]
   [461]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-1/igt@kms_force_connector_basic@force-load-detect.html
   [462]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-5/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-wc:
    - shard-rkl:          [SKIP][463] ([i915#14544] / [i915#1825]) -> [SKIP][464] ([i915#1825]) +9 other tests skip
   [463]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-wc.html
   [464]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-blt:
    - shard-rkl:          [SKIP][465] ([i915#15102]) -> [SKIP][466] ([i915#14544] / [i915#15102])
   [465]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-blt.html
   [466]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-mmap-gtt:
    - shard-dg1:          [SKIP][467] ([i915#15104] / [i915#4423]) -> [SKIP][468] ([i915#15104])
   [467]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-12/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-mmap-gtt.html
   [468]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-14/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscreen-pri-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt:
    - shard-dg2:          [SKIP][469] ([i915#15102] / [i915#3458]) -> [SKIP][470] ([i915#10433] / [i915#15102] / [i915#3458]) +1 other test skip
   [469]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-8/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt.html
   [470]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-4/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move:
    - shard-dg2:          [SKIP][471] ([i915#10433] / [i915#15102] / [i915#3458]) -> [SKIP][472] ([i915#15102] / [i915#3458]) +4 other tests skip
   [471]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-4/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move.html
   [472]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-5/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-gtt:
    - shard-rkl:          [SKIP][473] ([i915#1825]) -> [SKIP][474] ([i915#14544] / [i915#1825]) +17 other tests skip
   [473]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-gtt.html
   [474]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-blt:
    - shard-dg1:          [SKIP][475] ([i915#4423]) -> [SKIP][476]
   [475]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-17/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-blt.html
   [476]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-17/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@pipe-fbc-rte:
    - shard-rkl:          [SKIP][477] ([i915#9766]) -> [SKIP][478] ([i915#14544] / [i915#9766])
   [477]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@kms_frontbuffer_tracking@pipe-fbc-rte.html
   [478]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@pipe-fbc-rte.html

  * igt@kms_frontbuffer_tracking@psr-1p-offscreen-pri-shrfb-draw-mmap-cpu:
    - shard-rkl:          [SKIP][479] ([i915#14544] / [i915#15102]) -> [SKIP][480] ([i915#15102]) +1 other test skip
   [479]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-1p-offscreen-pri-shrfb-draw-mmap-cpu.html
   [480]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-8/igt@kms_frontbuffer_tracking@psr-1p-offscreen-pri-shrfb-draw-mmap-cpu.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-move:
    - shard-rkl:          [SKIP][481] ([i915#15102] / [i915#3023]) -> [SKIP][482] ([i915#14544] / [i915#15102] / [i915#3023]) +5 other tests skip
   [481]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-move.html
   [482]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@psr-suspend:
    - shard-rkl:          [SKIP][483] ([i915#14544] / [i915#15102] / [i915#3023]) -> [SKIP][484] ([i915#15102] / [i915#3023]) +3 other tests skip
   [483]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-suspend.html
   [484]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_frontbuffer_tracking@psr-suspend.html

  * igt@kms_hdr@brightness-with-hdr:
    - shard-mtlp:         [SKIP][485] ([i915#12713]) -> [SKIP][486] ([i915#1187] / [i915#12713])
   [485]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-mtlp-4/igt@kms_hdr@brightness-with-hdr.html
   [486]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-mtlp-1/igt@kms_hdr@brightness-with-hdr.html
    - shard-dg2:          [SKIP][487] ([i915#13331]) -> [SKIP][488] ([i915#12713])
   [487]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@kms_hdr@brightness-with-hdr.html
   [488]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-6/igt@kms_hdr@brightness-with-hdr.html
    - shard-tglu:         [SKIP][489] ([i915#1187] / [i915#12713]) -> [SKIP][490] ([i915#12713])
   [489]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-tglu-2/igt@kms_hdr@brightness-with-hdr.html
   [490]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-tglu-3/igt@kms_hdr@brightness-with-hdr.html

  * igt@kms_joiner@basic-big-joiner:
    - shard-rkl:          [SKIP][491] ([i915#14544] / [i915#15460]) -> [SKIP][492] ([i915#15460])
   [491]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_joiner@basic-big-joiner.html
   [492]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_joiner@basic-big-joiner.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-rkl:          [SKIP][493] ([i915#15815]) -> [SKIP][494] ([i915#14544] / [i915#15815])
   [493]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-4/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
   [494]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_plane@pixel-format-4-tiled-mtl-rc-ccs-cc-modifier-source-clamping:
    - shard-rkl:          [SKIP][495] ([i915#15709]) -> [SKIP][496] ([i915#14544] / [i915#15709]) +1 other test skip
   [495]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@kms_plane@pixel-format-4-tiled-mtl-rc-ccs-cc-modifier-source-clamping.html
   [496]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_plane@pixel-format-4-tiled-mtl-rc-ccs-cc-modifier-source-clamping.html

  * igt@kms_pm_lpsp@kms-lpsp:
    - shard-rkl:          [SKIP][497] ([i915#9340]) -> [SKIP][498] ([i915#3828])
   [497]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-3/igt@kms_pm_lpsp@kms-lpsp.html
   [498]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_pm_lpsp@kms-lpsp.html

  * igt@kms_pm_rpm@dpms-lpsp:
    - shard-rkl:          [SKIP][499] ([i915#14544] / [i915#15073]) -> [SKIP][500] ([i915#15073])
   [499]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_pm_rpm@dpms-lpsp.html
   [500]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_pm_rpm@dpms-lpsp.html

  * igt@kms_psr2_sf@fbc-pr-cursor-plane-move-continuous-exceed-sf:
    - shard-rkl:          [SKIP][501] ([i915#11520]) -> [SKIP][502] ([i915#11520] / [i915#14544]) +4 other tests skip
   [501]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_psr2_sf@fbc-pr-cursor-plane-move-continuous-exceed-sf.html
   [502]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_psr2_sf@fbc-pr-cursor-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_sf@pr-overlay-plane-update-continuous-sf:
    - shard-rkl:          [SKIP][503] ([i915#11520] / [i915#14544]) -> [SKIP][504] ([i915#11520]) +2 other tests skip
   [503]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_psr2_sf@pr-overlay-plane-update-continuous-sf.html
   [504]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-2/igt@kms_psr2_sf@pr-overlay-plane-update-continuous-sf.html

  * igt@kms_psr2_su@page_flip-xrgb8888:
    - shard-rkl:          [SKIP][505] ([i915#14544] / [i915#9683]) -> [SKIP][506] ([i915#9683])
   [505]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_psr2_su@page_flip-xrgb8888.html
   [506]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-4/igt@kms_psr2_su@page_flip-xrgb8888.html

  * igt@kms_psr@pr-cursor-mmap-gtt:
    - shard-rkl:          [SKIP][507] ([i915#1072] / [i915#14544] / [i915#9732]) -> [SKIP][508] ([i915#1072] / [i915#9732]) +4 other tests skip
   [507]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@kms_psr@pr-cursor-mmap-gtt.html
   [508]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@kms_psr@pr-cursor-mmap-gtt.html

  * igt@kms_psr@pr-sprite-mmap-gtt:
    - shard-dg1:          [SKIP][509] ([i915#1072] / [i915#4423] / [i915#9732]) -> [SKIP][510] ([i915#1072] / [i915#9732])
   [509]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg1-17/igt@kms_psr@pr-sprite-mmap-gtt.html
   [510]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg1-14/igt@kms_psr@pr-sprite-mmap-gtt.html

  * igt@kms_psr@psr-sprite-plane-onoff:
    - shard-rkl:          [SKIP][511] ([i915#1072] / [i915#9732]) -> [SKIP][512] ([i915#1072] / [i915#14544] / [i915#9732]) +7 other tests skip
   [511]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-8/igt@kms_psr@psr-sprite-plane-onoff.html
   [512]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_psr@psr-sprite-plane-onoff.html

  * igt@kms_rotation_crc@sprite-rotation-270:
    - shard-dg2:          [SKIP][513] ([i915#15867]) -> [SKIP][514] ([i915#12755] / [i915#15867])
   [513]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-dg2-10/igt@kms_rotation_crc@sprite-rotation-270.html
   [514]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-dg2-1/igt@kms_rotation_crc@sprite-rotation-270.html

  * igt@kms_scaling_modes@scaling-mode-none:
    - shard-rkl:          [SKIP][515] ([i915#3555]) -> [SKIP][516] ([i915#14544] / [i915#3555]) +1 other test skip
   [515]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@kms_scaling_modes@scaling-mode-none.html
   [516]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_scaling_modes@scaling-mode-none.html

  * igt@kms_vrr@negative-basic:
    - shard-rkl:          [SKIP][517] ([i915#3555] / [i915#9906]) -> [SKIP][518] ([i915#14544] / [i915#3555] / [i915#9906])
   [517]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-7/igt@kms_vrr@negative-basic.html
   [518]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@kms_vrr@negative-basic.html

  * igt@perf@mi-rpc:
    - shard-rkl:          [SKIP][519] ([i915#14544] / [i915#2434]) -> [SKIP][520] ([i915#2434])
   [519]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-6/igt@perf@mi-rpc.html
   [520]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-7/igt@perf@mi-rpc.html

  * igt@prime_vgem@fence-flip-hang:
    - shard-rkl:          [SKIP][521] ([i915#3708]) -> [SKIP][522] ([i915#14544] / [i915#3708])
   [521]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-2/igt@prime_vgem@fence-flip-hang.html
   [522]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@prime_vgem@fence-flip-hang.html

  * igt@sriov_basic@enable-vfs-autoprobe-on:
    - shard-rkl:          [SKIP][523] ([i915#9917]) -> [SKIP][524] ([i915#14544] / [i915#9917])
   [523]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18326/shard-rkl-5/igt@sriov_basic@enable-vfs-autoprobe-on.html
   [524]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/shard-rkl-6/igt@sriov_basic@enable-vfs-autoprobe-on.html

  
  [i915#10056]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10056
  [i915#10307]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10307
  [i915#10433]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10433
  [i915#10434]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10434
  [i915#10647]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10647
  [i915#1072]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1072
  [i915#11078]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11078
  [i915#11151]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11151
  [i915#11520]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11520
  [i915#11681]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11681
  [i915#1187]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1187
  [i915#11920]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11920
  [i915#12169]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12169
  [i915#12193]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12193
  [i915#12276]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12276
  [i915#12313]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12313
  [i915#12316]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12316
  [i915#12343]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12343
  [i915#12392]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12392
  [i915#12454]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12454
  [i915#12712]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12712
  [i915#12713]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12713
  [i915#12745]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12745
  [i915#12755]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12755
  [i915#12756]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12756
  [i915#12805]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12805
  [i915#12910]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12910
  [i915#13026]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13026
  [i915#13046]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13046
  [i915#13049]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13049
  [i915#13331]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13331
  [i915#13356]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13356
  [i915#13363]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13363
  [i915#13390]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13390
  [i915#13398]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13398
  [i915#13409]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13409
  [i915#13476]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13476
  [i915#13566]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13566
  [i915#13707]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13707
  [i915#13717]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13717
  [i915#13749]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13749
  [i915#13781]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13781
  [i915#13786]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13786
  [i915#13809]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13809
  [i915#13958]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13958
  [i915#14073]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14073
  [i915#14098]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14098
  [i915#14259]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14259
  [i915#14419]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14419
  [i915#14498]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14498
  [i915#14544]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14544
  [i915#14586]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14586
  [i915#14702]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14702
  [i915#15073]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15073
  [i915#15102]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15102
  [i915#15104]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15104
  [i915#15106]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15106
  [i915#15131]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15131
  [i915#15132]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15132
  [i915#15140]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15140
  [i915#15329]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15329
  [i915#15330]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15330
  [i915#15342]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15342
  [i915#15454]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15454
  [i915#15458]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15458
  [i915#15460]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15460
  [i915#15479]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15479
  [i915#15481]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15481
  [i915#15582]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15582
  [i915#15643]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15643
  [i915#15657]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15657
  [i915#15672]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15672
  [i915#15678]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15678
  [i915#15709]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15709
  [i915#15725]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15725
  [i915#15733]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15733
  [i915#15751]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15751
  [i915#15752]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15752
  [i915#15778]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15778
  [i915#15804]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15804
  [i915#15815]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15815
  [i915#15816]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15816
  [i915#15840]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15840
  [i915#15865]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15865
  [i915#15867]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15867
  [i915#1769]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1769
  [i915#1825]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1825
  [i915#1839]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1839
  [i915#2190]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/2190
  [i915#2434]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/2434
  [i915#2527]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/2527
  [i915#2658]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/2658
  [i915#280]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/280
  [i915#2856]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/2856
  [i915#3023]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3023
  [i915#3116]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3116
  [i915#3281]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3282
  [i915#3297]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3297
  [i915#3359]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3359
  [i915#3361]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3361
  [i915#3458]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3458
  [i915#3539]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3539
  [i915#3555]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3555
  [i915#3637]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3638
  [i915#3708]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3708
  [i915#3742]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3742
  [i915#3828]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3828
  [i915#3840]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3840
  [i915#3936]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3936
  [i915#4077]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4083
  [i915#4103]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4212
  [i915#4213]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4213
  [i915#4270]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4270
  [i915#4349]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4349
  [i915#4423]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4423
  [i915#4525]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4525
  [i915#4537]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4537
  [i915#4538]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4538
  [i915#4565]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4565
  [i915#4613]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4613
  [i915#4812]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4812
  [i915#4817]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4817
  [i915#4818]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4818
  [i915#4839]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4839
  [i915#4852]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4852
  [i915#4879]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4879
  [i915#5138]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5138
  [i915#5190]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5190
  [i915#5286]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5286
  [i915#5289]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5289
  [i915#5354]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5354
  [i915#5439]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5439
  [i915#5723]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5723
  [i915#5956]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5956
  [i915#6095]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6095
  [i915#6113]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6113
  [i915#6187]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6187
  [i915#6245]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6245
  [i915#6334]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6334
  [i915#6335]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6335
  [i915#6344]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6344
  [i915#6403]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6403
  [i915#658]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/658
  [i915#6590]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6590
  [i915#6621]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6621
  [i915#6953]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/6953
  [i915#7173]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/7173
  [i915#7582]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/7582
  [i915#7697]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/7697
  [i915#7828]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/7828
  [i915#8228]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8228
  [i915#8289]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8289
  [i915#8399]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8399
  [i915#8411]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8411
  [i915#8428]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8428
  [i915#8430]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8430
  [i915#8555]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8555
  [i915#8708]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8708
  [i915#8809]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8809
  [i915#8814]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8814
  [i915#8823]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8823
  [i915#8826]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/8826
  [i915#9323]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9323
  [i915#9340]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9340
  [i915#9433]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9433
  [i915#9457]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9457
  [i915#9683]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9683
  [i915#9688]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9688
  [i915#9723]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9723
  [i915#9732]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9732
  [i915#9766]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9766
  [i915#9809]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9809
  [i915#9878]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9878
  [i915#9906]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9906
  [i915#9917]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9917
  [i915#9934]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9934


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_8854 -> IGTPW_14974
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_18326: c8bad7becc008716c8475847328c549e178c813c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_14974: c162a18a4f192cdf0c0fce512f2e1695605d19db @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  IGT_8854: 93abaf0170728f69bc27577e5b405f7a2a01b6fd @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_14974/index.html

[-- Attachment #2: Type: text/html, Size: 174211 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-13 20:17 ` [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist Zbigniew Kempczyński
@ 2026-04-14  8:06   ` Krzysztof Karas
  2026-04-14 19:34     ` Zbigniew Kempczyński
  2026-04-14 20:33   ` Gustavo Sousa
  1 sibling, 1 reply; 34+ messages in thread
From: Krzysztof Karas @ 2026-04-14  8:06 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

Hi Zbigniew,

On 2026-04-13 at 22:17:26 +0200, Zbigniew Kempczyński wrote:
> We need to explicitly extract guc logs for failed tests so add hook
> script which does it after subtest/dynsubtest execution. As copying to
> attachments takes a lot of time do it only for failing subtests.
> 
> Adding this hook script to CI will extend execution time much and
> using allowlist is necessary. Instead of allowlist argument in the
> runner (previous attempt) now script filters such list on its own and
No need to mention development process (previous attempt,
previous version). Otherwise, it seems like you are referring
to the way this mechanism worked before your patch was
introduced, which is not true, as it did not exist yet.

I'd split this section and leave the following in the commit
message:

 Adding this hook script to CI will extend execution time much and
 using allowlist is necessary. The script filters such list on its
 own and decides when to move forward and do some post-test actions.

and move the reset to --- section:

 Using this approach, instead of previous versions, is more flexible,
 but moves decision to script what causes it to be more prone to bugs.

> decides when to move forward and do some post-test actions. Such
> approach is more flexible but moves decision to script what causes
> it is more prone buggy.
> 
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
> v2: install hook to datadir/hooks
> v3: migrate allowlist from runner to script
> ---
>  scripts/hooks/guc_copy.allowlist  |  2 ++
>  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
>  scripts/meson.build               |  3 ++
>  3 files changed, 52 insertions(+)
>  create mode 100644 scripts/hooks/guc_copy.allowlist
>  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
> 
> diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
> new file mode 100644
> index 0000000000..04cb3f8298
> --- /dev/null
> +++ b/scripts/hooks/guc_copy.allowlist
> @@ -0,0 +1,2 @@
> +igt@xe_compute@compute-square
> +igt@xe_exec_basic@once-basic@ccs0
Are these the most prone to fail in our CI? It would be good to
mention in the commit message why you chose these particular
subtests. 

[...]

-- 
Best Regards,
Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper
  2026-04-13 20:17 ` [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper Zbigniew Kempczyński
@ 2026-04-14  8:31   ` Krzysztof Karas
  0 siblings, 0 replies; 34+ messages in thread
From: Krzysztof Karas @ 2026-04-14  8:31 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

Hi Zbigniew,

On 2026-04-13 at 22:17:27 +0200, Zbigniew Kempczyński wrote:
> Upcoming patch which extends results.json to contain attachments
> is going to put file list in the array instead of key=value pair.
> Add helper which creates/finds array object in json structure.
This change should probably be squashed with the next one, so
the usage of this function is visible in the context and isn't
a standalone addition.

> 
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
>  runner/resultgen.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/runner/resultgen.c b/runner/resultgen.c
> index 29fc5cbb15..f8459385c3 100644
> --- a/runner/resultgen.c
> +++ b/runner/resultgen.c
> @@ -271,6 +271,20 @@ static struct json_t *get_or_create_json_object(struct json_t *base, const char
>  	return ret;
>  }
>  
> +static struct json_t *get_or_create_json_array(struct json_t *base, const char *key)
> +{
> +	struct json_t *ret = json_object_get(base, key);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = json_array();
> +	json_object_set_new(base, key, ret);
> +
> +	return ret;
> +}
> +
> +
Double newline here.

>  static void set_result(struct json_t *obj, const char *result)
>  {
>  	if (!result)
> -- 
> 2.43.0
> 

-- 
Best Regards,
Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-13 20:17 ` [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json Zbigniew Kempczyński
@ 2026-04-14  9:35   ` Krzysztof Karas
  2026-04-14 19:39     ` Zbigniew Kempczyński
  2026-04-14 21:39   ` Gustavo Sousa
  1 sibling, 1 reply; 34+ messages in thread
From: Krzysztof Karas @ 2026-04-14  9:35 UTC (permalink / raw)
  To: Zbigniew Kempczyński; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

Hi Zbigniew,

[...]

>  
>  #include <jansson.h>
> @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
>  	return true;
>  }
>  
> +struct json_t *tmp_tests;
> +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
> +				int typeflag, struct FTW *ftwbuf)
> +{
> +	struct json_t *obj = NULL, *attobj = NULL;
> +	(void)sb;
> +	(void)ftwbuf;
Is this so there are no unused parameter warnings?

> +
> +	if (typeflag == FTW_F) {
> +		char *p;
> +
> +		p = strstr(fpath + 2, "/");
> +		if (!p)
> +			return -1;
> +		*p = '\0'; /* temporary for acquiring the piglit name */
> +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
> +		attobj = get_or_create_json_array(obj, "attachments");
> +		*p = '/'; /* bring '/' back */
> +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
> +	} else if (typeflag == FTW_DP) {
> +		;
I think returning 0 here is not much of a code duplication and
would look better.

> +	} else {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static bool fill_from_attachments(int idirfd, struct json_t *tests)
> +{
> +	char attname[32];
> +	int attdirfd;
> +	DIR *currdir;
> +	int ret;
> +
> +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
> +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
> +		return false;
> +	}
> +
> +	currdir = opendir(".");
Should attdirfd and currdir be closed at the end of this
function? Or somewhere?

> +	fchdir(attdirfd);
> +
> +	/*
> +	 * ftw doesn't support passing user data so *tests has to be
> +	 * set to some global for being visible in callback function.
> +	 * As results.json is not processed in multiple threads it is
> +	 * not a big problem.
> +	 */
> +	tmp_tests = tests;
> +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
> +	fchdir(dirfd(currdir));
> +
> +	return ret ? false : true;
> +}
> +
>  static const char *result_from_exitcode(int exitcode)
>  {
>  	switch (exitcode) {
> @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
>  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
>  	}
>  
> +	if (!fill_from_attachments(dirfd, results->tests))
> +		fprintf(stderr, "Error parsing attachments directory\n");
> +
>  	override_results(entry->binary, &subtests, results->tests);
>  	prune_subtests(settings, entry, &subtests, results->tests);
>  
> -- 
> 2.43.0
> 

-- 
Best Regards,
Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-14  7:34   ` Krzysztof Karas
@ 2026-04-14 19:13     ` Zbigniew Kempczyński
  0 siblings, 0 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-14 19:13 UTC (permalink / raw)
  To: Krzysztof Karas; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

On Tue, Apr 14, 2026 at 07:34:41AM +0000, Krzysztof Karas wrote:
> Hi Zbigniew,
> 
> [...]
> 
> >  static bool clear_test_result_directory(int dirfd)
> >  {
> > -	int i;
> > +	int i, attdirfd;
> > +	int ret = true;
> >  
> >  	for (i = 0; i < _F_LAST; i++) {
> >  		if (remove_file(dirfd, filenames[i])) {
> > @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
> >  		}
> >  	}
> >  
> > -	return true;
> > +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> > +		errf("Cannot open attachments directory\n");
> > +		return false;
> > +	}
> > +
> > +	ret = clear_attachments_dir_recursively(attdirfd);
> > +	if (!ret)
> > +		errf("Cannot clear attachments dir recursively\n");
> > +
> > +	return ret;
> >  }
> >  
> >  static bool clear_old_results(char *path)
> > @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
> >  			close(dirfd);
> >  			return false;
> >  		}
> > +
> This is an unrelated newline, but I'd not block over it:
> Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>

You're right, this newline noise shouldn't be here. I'm going to
fix it in v4. Thanks for catching this.

--
Zbigniew

> 
> >  		close(resdirfd);
> >  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
> >  			errf("Warning: Result directory %s contains extra files\n",
> > diff --git a/runner/executor.h b/runner/executor.h
> > index 3b1cabcf55..bc6ac80dc4 100644
> > --- a/runner/executor.h
> > +++ b/runner/executor.h
> > @@ -25,6 +25,8 @@ enum {
> >  	_F_LAST,
> >  };
> >  
> > +#define DIR_ATTACHMENTS "attachments"
> > +
> >  bool open_output_files(int dirfd, int *fds, bool write);
> >  bool open_output_files_rdonly(int dirfd, int *fds);
> >  void close_outputs(int *fds);
> > -- 
> > 2.43.0
> > 
> 
> -- 
> Best Regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-13 20:17 ` [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks Zbigniew Kempczyński
  2026-04-14  7:34   ` Krzysztof Karas
@ 2026-04-14 19:27   ` Gustavo Sousa
  2026-04-15  5:34     ` Zbigniew Kempczyński
  1 sibling, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-14 19:27 UTC (permalink / raw)
  To: Zbigniew Kempczyński, igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> Results parsing is currently limited to few predefined files.
>
> Create "attachments" directory and export full path of created directory
> to be used within hooks. From now on environment variable
> IGT_RUNNER_ATTACHMENTS_DIR become visible when igt_runner is used
> to execute tests. This env contains directory where subtests/dynsubtests
> may write auxiliary files which finally be included in results.json.
>
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
> v2: simplify attachment dirname concatenation (Kamil)
>     remove files in attachments dir when overwrite is set (Kamil)
> v3: unify 'attdir*' variables (Krzysztof)
>     do recursive removal in attachments directories (Gustavo)
> ---
>  lib/igt_hook.c    |  4 +++
>  runner/executor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++--
>  runner/executor.h |  2 ++
>  3 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/lib/igt_hook.c b/lib/igt_hook.c
> index f86ed56f72..b8f25b6c7a 100644
> --- a/lib/igt_hook.c
> +++ b/lib/igt_hook.c
> @@ -518,5 +518,9 @@ available to the command:\n\
>  \n\
>  Note that %s can be passed multiple times. Each descriptor is evaluated in turn\n\
>  when matching events and running hook commands.\n\
> +\n\
> +When executed by the igt_runner, environment IGT_RUNNER_ATTACHMENTS_DIR\n\
> +is passed additionally to the hook script. It contains directory where\n\
> +script may write additional attachments like guc logs, etc.\n\
>  ", option_name);
>  }
> diff --git a/runner/executor.c b/runner/executor.c
> index 1485b59d1f..af39b12aea 100644
> --- a/runner/executor.c
> +++ b/runner/executor.c
> @@ -1,6 +1,7 @@
>  #include <ctype.h>
>  #include <errno.h>
>  #include <fcntl.h>
> +#include <ftw.h>
>  #ifdef ANDROID
>  #include "android/glib.h"
>  #else
> @@ -1779,17 +1780,22 @@ static int execute_next_entry(struct execute_state *state,
>  	int errpipe[2] = { -1, -1 };
>  	int socket[2] = { -1, -1 };
>  	int outfd, errfd, socketfd;
> -	char name[32];
> +	char name[32], attname[32];
> +	char attdirname[PATH_MAX];
>  	pid_t child;
>  	int result;
>  	size_t idx = state->next;
>  
>  	snprintf(name, sizeof(name), "%zd", idx);
> +	snprintf(attname, sizeof(attname), "%zd/%s", idx, DIR_ATTACHMENTS);
>  	mkdirat(resdirfd, name, 0777);
> +	mkdirat(resdirfd, attname, 0777);
>  	if ((idirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
>  		errf("Error accessing individual test result directory\n");
>  		return -1;
>  	}
> +	snprintf(attdirname, sizeof(attdirname), "%s/%s",
> +		 settings->results_path, attname);
>  
>  	if (!open_output_files(idirfd, outputs, true)) {
>  		errf("Error opening output files\n");
> @@ -1870,6 +1876,7 @@ static int execute_next_entry(struct execute_state *state,
>  			setenv("IGT_RUNNER_SOCKET_FD", envstring, 1);
>  		}
>  		setenv("IGT_SENTINEL_ON_STDERR", "1", 1);
> +		setenv("IGT_RUNNER_ATTACHMENTS_DIR", attdirname, 1);
>  
>  		execute_test_process(outfd, errfd, socketfd, settings, entry);
>  		/* unreachable */
> @@ -1948,9 +1955,61 @@ static int remove_file(int dirfd, const char *name)
>  	return unlinkat(dirfd, name, 0) && errno != ENOENT;
>  }
>  
> +static int ftw_attachment_removal(const char *fpath, const struct stat *sb,
> +				  int typeflag, struct FTW *ftwbuf)
> +{
> +	(void)sb;
> +	(void)ftwbuf;

I was able to compile without warnings after dropping this.  Is there a
reason to keep them here?

> +
> +	if (typeflag == FTW_F) {
> +		if (unlink(fpath)) {
> +			errf("Cannot remove file %s\n", fpath);

Maybe append strerror(errno) to the message here?

> +			return -1;
> +		}
> +	} else if (typeflag == FTW_DP) {
> +		if (rmdir(fpath)) {
> +			errf("Cannot remove directory %s\n", fpath);

Ditto.

> +			return -1;
> +		}
> +	} else {
> +		errf("Cannot remove %s (unsupported file type)\n", fpath);
> +		return -1;

I think it would be sensible to drop symbolic links as well (I think it
could be handled in the same brace for FTW_F.

> +	}

I think this would look nicer if it was handled with a "switch"
statement.

> +
> +	return 0;
> +}
> +
> +static bool clear_attachments_dir_recursively(int attdirfd)
> +{
> +	char attdirname[PATH_MAX];
> +	DIR *currdir;
> +	int ret;
> +
> +	currdir = opendir(".");

Why do we need this call?

> +	fchdir(attdirfd);
> +	getcwd(attdirname, sizeof(attdirname));
> +
> +	/* Sanity check we're in attachments directory structure */
> +	if (!strstr(attdirname, DIR_ATTACHMENTS)) {
> +		errf("Cowardly refusing removing in directory which is not "
> +		     "attachments directory [currdir: %s]!\n", attdirname);
> +		ret = -1;
> +		goto out;
> +	}

This function is static and only called for DIR_ATTACHMENTS.  I believe
this check is unnecessary.

> +
> +	ret = nftw(attdirname, ftw_attachment_removal, 4, FTW_PHYS | FTW_DEPTH);
> +
> +out:
> +	fchdir(dirfd(currdir));
> +	closedir(currdir);
> +
> +	return ret ? false : true;
> +}
> +
>  static bool clear_test_result_directory(int dirfd)

I think we need to have the path to the test result dir passed as
argument here so that we can build attdirname without having the change
dir + get cwd dance.

>  {
> -	int i;
> +	int i, attdirfd;
> +	int ret = true;

I guess we don't need this ret variable. If the removal of the
attachments directory fails, we can just print an error message and
return false.

>  
>  	for (i = 0; i < _F_LAST; i++) {
>  		if (remove_file(dirfd, filenames[i])) {
> @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
>  		}
>  	}
>  
> -	return true;
> +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> +		errf("Cannot open attachments directory\n");
> +		return false;
> +	}
> +
> +	ret = clear_attachments_dir_recursively(attdirfd);
> +	if (!ret)
> +		errf("Cannot clear attachments dir recursively\n");

Why not simply call nftw() directly from here? I don't see much value in
having the function clear_attachments_dir_recursively().

--
Gustavo Sousa

> +
> +	return ret;
>  }
>  
>  static bool clear_old_results(char *path)
> @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
>  			close(dirfd);
>  			return false;
>  		}
> +
>  		close(resdirfd);
>  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
>  			errf("Warning: Result directory %s contains extra files\n",
> diff --git a/runner/executor.h b/runner/executor.h
> index 3b1cabcf55..bc6ac80dc4 100644
> --- a/runner/executor.h
> +++ b/runner/executor.h
> @@ -25,6 +25,8 @@ enum {
>  	_F_LAST,
>  };
>  
> +#define DIR_ATTACHMENTS "attachments"
> +
>  bool open_output_files(int dirfd, int *fds, bool write);
>  bool open_output_files_rdonly(int dirfd, int *fds);
>  void close_outputs(int *fds);
> -- 
> 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-14  8:06   ` Krzysztof Karas
@ 2026-04-14 19:34     ` Zbigniew Kempczyński
  0 siblings, 0 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-14 19:34 UTC (permalink / raw)
  To: Krzysztof Karas; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

On Tue, Apr 14, 2026 at 08:06:52AM +0000, Krzysztof Karas wrote:
> Hi Zbigniew,
> 
> On 2026-04-13 at 22:17:26 +0200, Zbigniew Kempczyński wrote:
> > We need to explicitly extract guc logs for failed tests so add hook
> > script which does it after subtest/dynsubtest execution. As copying to
> > attachments takes a lot of time do it only for failing subtests.
> > 
> > Adding this hook script to CI will extend execution time much and
> > using allowlist is necessary. Instead of allowlist argument in the
> > runner (previous attempt) now script filters such list on its own and
> No need to mention development process (previous attempt,
> previous version). Otherwise, it seems like you are referring
> to the way this mechanism worked before your patch was
> introduced, which is not true, as it did not exist yet.

To be honest I wondered should I add an info about previous attempt
regarding allowlist implementation as a runner argument. I know
implementation wasn't yet merged, but decision why scripts have to
filter allowed tests on their own might be important for the reader.
Short info we considered to contain allowlist in the runner might
answer questions why we migrated this responsibility to script itself,
even if it is at the end of food chain.

> 
> I'd split this section and leave the following in the commit
> message:
> 
>  Adding this hook script to CI will extend execution time much and
>  using allowlist is necessary. The script filters such list on its
>  own and decides when to move forward and do some post-test actions.
> 
> and move the reset to --- section:
> 
>  Using this approach, instead of previous versions, is more flexible,
>  but moves decision to script what causes it to be more prone to bugs.
> 
> > decides when to move forward and do some post-test actions. Such
> > approach is more flexible but moves decision to script what causes
> > it is more prone buggy.
> > 
> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> > ---
> > v2: install hook to datadir/hooks
> > v3: migrate allowlist from runner to script
> > ---
> >  scripts/hooks/guc_copy.allowlist  |  2 ++
> >  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
> >  scripts/meson.build               |  3 ++
> >  3 files changed, 52 insertions(+)
> >  create mode 100644 scripts/hooks/guc_copy.allowlist
> >  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
> > 
> > diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
> > new file mode 100644
> > index 0000000000..04cb3f8298
> > --- /dev/null
> > +++ b/scripts/hooks/guc_copy.allowlist
> > @@ -0,0 +1,2 @@
> > +igt@xe_compute@compute-square
> > +igt@xe_exec_basic@once-basic@ccs0
> Are these the most prone to fail in our CI? It would be good to
> mention in the commit message why you chose these particular
> subtests. 

Good question. I've picked random tests to create an allowlist and
parse it in a script. In real world scenario we should modify this file
according to bugs we notice in which we want to dump guc logs.

There're two goals I would like to achieve - dump guc logs for tests
which guc log is important, and second - how to not slow down CI much.
Everything I propose adds some overhead to CI (execution scripts
modification, etc), but as guc log is important from debug perspective
and we have to collect it even at cost of introducing some complexity
in the CI workflow.

--
Zbigniew

> 
> [...]
> 
> -- 
> Best Regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-14  9:35   ` Krzysztof Karas
@ 2026-04-14 19:39     ` Zbigniew Kempczyński
  0 siblings, 0 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-14 19:39 UTC (permalink / raw)
  To: Krzysztof Karas; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop

On Tue, Apr 14, 2026 at 09:35:37AM +0000, Krzysztof Karas wrote:
> Hi Zbigniew,
> 
> [...]
> 
> >  
> >  #include <jansson.h>
> > @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
> >  	return true;
> >  }
> >  
> > +struct json_t *tmp_tests;
> > +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
> > +				int typeflag, struct FTW *ftwbuf)
> > +{
> > +	struct json_t *obj = NULL, *attobj = NULL;
> > +	(void)sb;
> > +	(void)ftwbuf;
> Is this so there are no unused parameter warnings?

Yes, that's my habit to mark unused arguments as void to silence
the compiler warnings.

> 
> > +
> > +	if (typeflag == FTW_F) {
> > +		char *p;
> > +
> > +		p = strstr(fpath + 2, "/");
> > +		if (!p)
> > +			return -1;
> > +		*p = '\0'; /* temporary for acquiring the piglit name */
> > +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
> > +		attobj = get_or_create_json_array(obj, "attachments");
> > +		*p = '/'; /* bring '/' back */
> > +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
> > +	} else if (typeflag == FTW_DP) {
> > +		;
> I think returning 0 here is not much of a code duplication and
> would look better.

Ok, v4 will contain the change.

> 
> > +	} else {
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static bool fill_from_attachments(int idirfd, struct json_t *tests)
> > +{
> > +	char attname[32];
> > +	int attdirfd;
> > +	DIR *currdir;
> > +	int ret;
> > +
> > +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
> > +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> > +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
> > +		return false;
> > +	}
> > +
> > +	currdir = opendir(".");
> Should attdirfd and currdir be closed at the end of this
> function? Or somewhere?

Yes, I missed the cleanup. Will be fixed in v4, thanks!

--
Zbigniew

> 
> > +	fchdir(attdirfd);
> > +
> > +	/*
> > +	 * ftw doesn't support passing user data so *tests has to be
> > +	 * set to some global for being visible in callback function.
> > +	 * As results.json is not processed in multiple threads it is
> > +	 * not a big problem.
> > +	 */
> > +	tmp_tests = tests;
> > +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
> > +	fchdir(dirfd(currdir));
> > +
> > +	return ret ? false : true;
> > +}
> > +
> >  static const char *result_from_exitcode(int exitcode)
> >  {
> >  	switch (exitcode) {
> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
> >  	}
> >  
> > +	if (!fill_from_attachments(dirfd, results->tests))
> > +		fprintf(stderr, "Error parsing attachments directory\n");
> > +
> >  	override_results(entry->binary, &subtests, results->tests);
> >  	prune_subtests(settings, entry, &subtests, results->tests);
> >  
> > -- 
> > 2.43.0
> > 
> 
> -- 
> Best Regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-13 20:17 ` [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist Zbigniew Kempczyński
  2026-04-14  8:06   ` Krzysztof Karas
@ 2026-04-14 20:33   ` Gustavo Sousa
  2026-04-15  8:23     ` Zbigniew Kempczyński
  1 sibling, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-14 20:33 UTC (permalink / raw)
  To: Zbigniew Kempczyński, igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> We need to explicitly extract guc logs for failed tests so add hook
> script which does it after subtest/dynsubtest execution. As copying to
> attachments takes a lot of time do it only for failing subtests.
>
> Adding this hook script to CI will extend execution time much and
> using allowlist is necessary. Instead of allowlist argument in the
> runner (previous attempt) now script filters such list on its own and
> decides when to move forward and do some post-test actions. Such
> approach is more flexible but moves decision to script what causes
> it is more prone buggy.
>
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
> v2: install hook to datadir/hooks
> v3: migrate allowlist from runner to script
> ---
>  scripts/hooks/guc_copy.allowlist  |  2 ++
>  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
>  scripts/meson.build               |  3 ++
>  3 files changed, 52 insertions(+)
>  create mode 100644 scripts/hooks/guc_copy.allowlist
>  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
>
> diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
> new file mode 100644
> index 0000000000..04cb3f8298
> --- /dev/null
> +++ b/scripts/hooks/guc_copy.allowlist

Do we want really want the allowlist to be part distributed with IGT? I
think we should default it to no allowlist and then CI (or whoever is
using the hook) defines it if that's desired.

> @@ -0,0 +1,2 @@
> +igt@xe_compute@compute-square
> +igt@xe_exec_basic@once-basic@ccs0
> diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
> new file mode 100755
> index 0000000000..595cf5205e
> --- /dev/null
> +++ b/scripts/hooks/guc_copy_on_fail.sh

Maybe guc_log_on_fail.sh? I think it is more descriptive than
guc_copy_*, since the latter is a bit vague about what is being copied.

> @@ -0,0 +1,47 @@
> +#!/bin/bash
> +
> +# Hook script for copying guc.log.
> +# Suggested usage with:
> +# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
> +
> +# Copy only for failed subtests as this is time-consuming
> +if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
> +	exit 0
> +fi
> +
> +# Process and copy guc logs only for those specified in allowlist
> +ALLOWLIST="guc_copy.allowlist"
> +scriptdir=$(dirname $(realpath $0))

It is safer to use "$0" above.

> +
> +if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
> +	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
> +	exit 0
> +fi

Well, we could allow the hook user to define the output and default it
to "$IGT_RUNNER_ATTACHMENTS_DIR/guc_log" if not passed and
$IGT_RUNNER_ATTACHMENTS_DIR is defined.  Otherwise, we should error out
IMO (i.e. exit 1).

As an example, someone could be calling a single test binary directly
and want to use this hook.

We could do some simple argument parsing here or, to make it simpler,
establish that IGT_HOOKS_GUC_LOG_DEST would be such an input variable
(and document it in the doc comment at the start of the script).

> +
> +cd "$IGT_RUNNER_ATTACHMENTS_DIR"
> +
> +# Look for allowlist in following places:
> +# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
> +# 2. Try in <scriptdir>
> +
> +if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
> +	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
> +else
> +	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
> +fi

I would just receive the allowlist path from CLI args or, to make it
simpler, from an environment like IGT_HOOKS_GUC_LOG_ALLOWLIST; and I
think we should default to not using any allowlist if none was passed.

> +
> +if [ ! -e "${ALLOWLIST_PATH}" ]; then
> +	exit 0
> +fi
> +
> +STNAME="${IGT_HOOK_TEST_FULLNAME}"
> +echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
> +if [ $? -ne 0 ]; then
> +	exit 0
> +fi

This can simplified with:

     if ! echo "$IGT_HOOK_TEST_FULLNAME" | grep -q -f "$ALLOWLIST_PATH"; then
        exit 0;
     fi

> +
> +for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do

Suggestion: use $(cd /sys/kernel/debug/dri && find -name guc_log)...

> +	attout=$(echo ${log:23} | sed -e 's/\//_/g')

...and then here we don't need this line...

> +	mkdir -p "${STNAME}"
> +	cp "$log" "${STNAME}/${attout}"

...and here we can simply do: cp "$log" "$STNAME/${log////_}".

One issue with the find command above is that we could potentially
collect GuC log for other device (not the one under test).  I know that
IGT supports selecting a device via the environment variable
IGT_DEVICE.  I wonder if we should make it set an environment for the
device under test; we could use a different variable name to avoid
issues with the existing one.

--
Gustavo Sousa

> +done
> diff --git a/scripts/meson.build b/scripts/meson.build
> index 6e64065c5e..2ce961898d 100644
> --- a/scripts/meson.build
> +++ b/scripts/meson.build
> @@ -15,3 +15,6 @@ endif
>  igt_doc_script = find_program('igt_doc.py', required : build_testplan)
>  gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
>  generate_iga64_codes = find_program('generate_iga64_codes')
> +
> +install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
> +install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
> -- 
> 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-13 20:17 ` [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json Zbigniew Kempczyński
  2026-04-14  9:35   ` Krzysztof Karas
@ 2026-04-14 21:39   ` Gustavo Sousa
  2026-04-15  6:31     ` Zbigniew Kempczyński
  1 sibling, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-14 21:39 UTC (permalink / raw)
  To: Zbigniew Kempczyński, igt-dev
  Cc: Zbigniew Kempczyński, Kamil Konieczny, Ryszard Knop,
	Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> Add list of filenames which were created by hooks in attachments directory
> (like GuC log copy) to results.json for allow presenting it in CI.
>
> Due to lack of userdata pointer in nftw() implementation main json
> object is passed via temporary static variable. It shouldn't be the
> problem because results.json is created in single thread. This change
> is not too elegant but allows to minimize the code change and is
> much easier to read comparing to recursive readdir().
>
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Ryszard Knop <ryszard.knop@intel.com>
> Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
>  runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
>
> diff --git a/runner/resultgen.c b/runner/resultgen.c
> index f8459385c3..d37f01a433 100644
> --- a/runner/resultgen.c
> +++ b/runner/resultgen.c
> @@ -1,11 +1,14 @@
>  #include <assert.h>
>  #include <ctype.h>
> +#include <dirent.h>
>  #include <fcntl.h>
> +#include <ftw.h>
>  #include <inttypes.h>
>  #include <stdio.h>
>  #include <string.h>
>  #include <sys/mman.h>
>  #include <sys/stat.h>
> +#include <sys/types.h>
>  #include <unistd.h>
>  
>  #include <jansson.h>
> @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
>  	return true;
>  }
>  
> +struct json_t *tmp_tests;
> +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
> +				int typeflag, struct FTW *ftwbuf)
> +{
> +	struct json_t *obj = NULL, *attobj = NULL;
> +	(void)sb;
> +	(void)ftwbuf;
> +
> +	if (typeflag == FTW_F) {
> +		char *p;
> +
> +		p = strstr(fpath + 2, "/");
> +		if (!p)
> +			return -1;
> +		*p = '\0'; /* temporary for acquiring the piglit name */
> +		obj = get_or_create_json_object(tmp_tests, fpath + 2);

For this to be trully recursive, I think we should create the JSON
object in the FTW_DP case.

> +		attobj = get_or_create_json_array(obj, "attachments");
> +		*p = '/'; /* bring '/' back */
> +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
> +	} else if (typeflag == FTW_DP) {
> +		;
> +	} else {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static bool fill_from_attachments(int idirfd, struct json_t *tests)
> +{
> +	char attname[32];
> +	int attdirfd;
> +	DIR *currdir;
> +	int ret;
> +
> +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
> +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
> +		return false;
> +	}
> +
> +	currdir = opendir(".");
> +	fchdir(attdirfd);
> +
> +	/*
> +	 * ftw doesn't support passing user data so *tests has to be
> +	 * set to some global for being visible in callback function.
> +	 * As results.json is not processed in multiple threads it is
> +	 * not a big problem.
> +	 */
> +	tmp_tests = tests;
> +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);

I think another option is to use fts(3)? Since it is a streaming API,
you can keep the state (i.e. the current json object) as a local
variable and update as you walk the tree.

It seems it is not POSIX though.  Not sure if that's a real issue for
IGT, since stuff in IGT are supposed to run on Linux, right?

Thinking back, I guess it could fts(3) could even be used for the
recursive removal.

--
Gustavo Sousa

> +	fchdir(dirfd(currdir));
> +
> +	return ret ? false : true;
> +}
> +
>  static const char *result_from_exitcode(int exitcode)
>  {
>  	switch (exitcode) {
> @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
>  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
>  	}
>  
> +	if (!fill_from_attachments(dirfd, results->tests))
> +		fprintf(stderr, "Error parsing attachments directory\n");
> +
>  	override_results(entry->binary, &subtests, results->tests);
>  	prune_subtests(settings, entry, &subtests, results->tests);
>  
> -- 
> 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-14 19:27   ` Gustavo Sousa
@ 2026-04-15  5:34     ` Zbigniew Kempczyński
  2026-04-15 13:48       ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15  5:34 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Tue, Apr 14, 2026 at 04:27:48PM -0300, Gustavo Sousa wrote:
> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> 
> > Results parsing is currently limited to few predefined files.
> >
> > Create "attachments" directory and export full path of created directory
> > to be used within hooks. From now on environment variable
> > IGT_RUNNER_ATTACHMENTS_DIR become visible when igt_runner is used
> > to execute tests. This env contains directory where subtests/dynsubtests
> > may write auxiliary files which finally be included in results.json.
> >
> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> > ---
> > v2: simplify attachment dirname concatenation (Kamil)
> >     remove files in attachments dir when overwrite is set (Kamil)
> > v3: unify 'attdir*' variables (Krzysztof)
> >     do recursive removal in attachments directories (Gustavo)
> > ---
> >  lib/igt_hook.c    |  4 +++
> >  runner/executor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++--
> >  runner/executor.h |  2 ++
> >  3 files changed, 78 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/igt_hook.c b/lib/igt_hook.c
> > index f86ed56f72..b8f25b6c7a 100644
> > --- a/lib/igt_hook.c
> > +++ b/lib/igt_hook.c
> > @@ -518,5 +518,9 @@ available to the command:\n\
> >  \n\
> >  Note that %s can be passed multiple times. Each descriptor is evaluated in turn\n\
> >  when matching events and running hook commands.\n\
> > +\n\
> > +When executed by the igt_runner, environment IGT_RUNNER_ATTACHMENTS_DIR\n\
> > +is passed additionally to the hook script. It contains directory where\n\
> > +script may write additional attachments like guc logs, etc.\n\
> >  ", option_name);
> >  }
> > diff --git a/runner/executor.c b/runner/executor.c
> > index 1485b59d1f..af39b12aea 100644
> > --- a/runner/executor.c
> > +++ b/runner/executor.c
> > @@ -1,6 +1,7 @@
> >  #include <ctype.h>
> >  #include <errno.h>
> >  #include <fcntl.h>
> > +#include <ftw.h>
> >  #ifdef ANDROID
> >  #include "android/glib.h"
> >  #else
> > @@ -1779,17 +1780,22 @@ static int execute_next_entry(struct execute_state *state,
> >  	int errpipe[2] = { -1, -1 };
> >  	int socket[2] = { -1, -1 };
> >  	int outfd, errfd, socketfd;
> > -	char name[32];
> > +	char name[32], attname[32];
> > +	char attdirname[PATH_MAX];
> >  	pid_t child;
> >  	int result;
> >  	size_t idx = state->next;
> >  
> >  	snprintf(name, sizeof(name), "%zd", idx);
> > +	snprintf(attname, sizeof(attname), "%zd/%s", idx, DIR_ATTACHMENTS);
> >  	mkdirat(resdirfd, name, 0777);
> > +	mkdirat(resdirfd, attname, 0777);
> >  	if ((idirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> >  		errf("Error accessing individual test result directory\n");
> >  		return -1;
> >  	}
> > +	snprintf(attdirname, sizeof(attdirname), "%s/%s",
> > +		 settings->results_path, attname);
> >  
> >  	if (!open_output_files(idirfd, outputs, true)) {
> >  		errf("Error opening output files\n");
> > @@ -1870,6 +1876,7 @@ static int execute_next_entry(struct execute_state *state,
> >  			setenv("IGT_RUNNER_SOCKET_FD", envstring, 1);
> >  		}
> >  		setenv("IGT_SENTINEL_ON_STDERR", "1", 1);
> > +		setenv("IGT_RUNNER_ATTACHMENTS_DIR", attdirname, 1);
> >  
> >  		execute_test_process(outfd, errfd, socketfd, settings, entry);
> >  		/* unreachable */
> > @@ -1948,9 +1955,61 @@ static int remove_file(int dirfd, const char *name)
> >  	return unlinkat(dirfd, name, 0) && errno != ENOENT;
> >  }
> >  
> > +static int ftw_attachment_removal(const char *fpath, const struct stat *sb,
> > +				  int typeflag, struct FTW *ftwbuf)
> > +{
> > +	(void)sb;
> > +	(void)ftwbuf;
> 
> I was able to compile without warnings after dropping this.  Is there a
> reason to keep them here?

I'm trying to keep code I write clean according to warnings. We have
'-Wno-unused-parameter' in meson.build so above lines could be dropped.
But if someone will decide to clean the code I won't give him/her more
work. And imo this is in good taste to annotate unused arguments.

> 
> > +
> > +	if (typeflag == FTW_F) {
> > +		if (unlink(fpath)) {
> > +			errf("Cannot remove file %s\n", fpath);
> 
> Maybe append strerror(errno) to the message here?

Yes, why not.

> 
> > +			return -1;
> > +		}
> > +	} else if (typeflag == FTW_DP) {
> > +		if (rmdir(fpath)) {
> > +			errf("Cannot remove directory %s\n", fpath);
> 
> Ditto.
> 
> > +			return -1;
> > +		}
> > +	} else {
> > +		errf("Cannot remove %s (unsupported file type)\n", fpath);
> > +		return -1;
> 
> I think it would be sensible to drop symbolic links as well (I think it
> could be handled in the same brace for FTW_F.

I wondered about this, but I would be strict - only files and dirs
are allowed in the attachments directory. What for user/script would do
symbolic links there?

> 
> > +	}
> 
> I think this would look nicer if it was handled with a "switch"
> statement.

Agree, switch with default will look better in this case. I'll
replace if's to switch in v4.

> 
> > +
> > +	return 0;
> > +}
> > +
> > +static bool clear_attachments_dir_recursively(int attdirfd)
> > +{
> > +	char attdirname[PATH_MAX];
> > +	DIR *currdir;
> > +	int ret;
> > +
> > +	currdir = opendir(".");
> 
> Why do we need this call?

nftw() requires path, not fd so I have to ensure I leave working
directory intact when I quit the function. I don't know any method
apart of fchdir/getcwd() to get dirname I would like to pass to
nftw(). And I won't assume I know where's current working dir.

> 
> > +	fchdir(attdirfd);
> > +	getcwd(attdirname, sizeof(attdirname));
> > +
> > +	/* Sanity check we're in attachments directory structure */
> > +	if (!strstr(attdirname, DIR_ATTACHMENTS)) {
> > +		errf("Cowardly refusing removing in directory which is not "
> > +		     "attachments directory [currdir: %s]!\n", attdirname);
> > +		ret = -1;
> > +		goto out;
> > +	}
> 
> This function is static and only called for DIR_ATTACHMENTS.  I believe
> this check is unnecessary.

Assuming no bug is here you're right, but I would like to do double check
directory content I want to remove is really I expect to.

> 
> > +
> > +	ret = nftw(attdirname, ftw_attachment_removal, 4, FTW_PHYS | FTW_DEPTH);
> > +
> > +out:
> > +	fchdir(dirfd(currdir));
> > +	closedir(currdir);
> > +
> > +	return ret ? false : true;
> > +}
> > +
> >  static bool clear_test_result_directory(int dirfd)
> 
> I think we need to have the path to the test result dir passed as
> argument here so that we can build attdirname without having the change
> dir + get cwd dance.

I didn't want to rewrite clear_old_results() function. Current code
uses mostly fd's and only place where I really need path is nftw().
I will rewrite to passing paths if you insist but personally I wouldn't
do this.

> 
> >  {
> > -	int i;
> > +	int i, attdirfd;
> > +	int ret = true;
> 
> I guess we don't need this ret variable. If the removal of the
> attachments directory fails, we can just print an error message and
> return false.

Ok.

> 
> >  
> >  	for (i = 0; i < _F_LAST; i++) {
> >  		if (remove_file(dirfd, filenames[i])) {
> > @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
> >  		}
> >  	}
> >  
> > -	return true;
> > +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> > +		errf("Cannot open attachments directory\n");
> > +		return false;
> > +	}
> > +
> > +	ret = clear_attachments_dir_recursively(attdirfd);
> > +	if (!ret)
> > +		errf("Cannot clear attachments dir recursively\n");
> 
> Why not simply call nftw() directly from here? I don't see much value in
> having the function clear_attachments_dir_recursively().

I created a separate function because I like dividing logical tasks
to separate functions. I can unfold this function here if you think
this will be better.

--
Zbigniew

> 
> --
> Gustavo Sousa
> 
> > +
> > +	return ret;
> >  }
> >  
> >  static bool clear_old_results(char *path)
> > @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
> >  			close(dirfd);
> >  			return false;
> >  		}
> > +
> >  		close(resdirfd);
> >  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
> >  			errf("Warning: Result directory %s contains extra files\n",
> > diff --git a/runner/executor.h b/runner/executor.h
> > index 3b1cabcf55..bc6ac80dc4 100644
> > --- a/runner/executor.h
> > +++ b/runner/executor.h
> > @@ -25,6 +25,8 @@ enum {
> >  	_F_LAST,
> >  };
> >  
> > +#define DIR_ATTACHMENTS "attachments"
> > +
> >  bool open_output_files(int dirfd, int *fds, bool write);
> >  bool open_output_files_rdonly(int dirfd, int *fds);
> >  void close_outputs(int *fds);
> > -- 
> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-14 21:39   ` Gustavo Sousa
@ 2026-04-15  6:31     ` Zbigniew Kempczyński
  2026-04-15 12:16       ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15  6:31 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Tue, Apr 14, 2026 at 06:39:28PM -0300, Gustavo Sousa wrote:
> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> 
> > Add list of filenames which were created by hooks in attachments directory
> > (like GuC log copy) to results.json for allow presenting it in CI.
> >
> > Due to lack of userdata pointer in nftw() implementation main json
> > object is passed via temporary static variable. It shouldn't be the
> > problem because results.json is created in single thread. This change
> > is not too elegant but allows to minimize the code change and is
> > much easier to read comparing to recursive readdir().
> >
> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> > ---
> >  runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 63 insertions(+)
> >
> > diff --git a/runner/resultgen.c b/runner/resultgen.c
> > index f8459385c3..d37f01a433 100644
> > --- a/runner/resultgen.c
> > +++ b/runner/resultgen.c
> > @@ -1,11 +1,14 @@
> >  #include <assert.h>
> >  #include <ctype.h>
> > +#include <dirent.h>
> >  #include <fcntl.h>
> > +#include <ftw.h>
> >  #include <inttypes.h>
> >  #include <stdio.h>
> >  #include <string.h>
> >  #include <sys/mman.h>
> >  #include <sys/stat.h>
> > +#include <sys/types.h>
> >  #include <unistd.h>
> >  
> >  #include <jansson.h>
> > @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
> >  	return true;
> >  }
> >  
> > +struct json_t *tmp_tests;
> > +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
> > +				int typeflag, struct FTW *ftwbuf)
> > +{
> > +	struct json_t *obj = NULL, *attobj = NULL;
> > +	(void)sb;
> > +	(void)ftwbuf;
> > +
> > +	if (typeflag == FTW_F) {
> > +		char *p;
> > +
> > +		p = strstr(fpath + 2, "/");
> > +		if (!p)
> > +			return -1;
> > +		*p = '\0'; /* temporary for acquiring the piglit name */
> > +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
> 
> For this to be trully recursive, I think we should create the JSON
> object in the FTW_DP case.

What for? Imo attachments array for test/subtest which contains
relative paths from test/subtest is enough. I see no value by adding
recursive arrays apart of increasing complexity to the code. Be aware CI has
to present these attachments as well, so more we complicate results.json
more work will be on CI side to alter javascript.

> 
> > +		attobj = get_or_create_json_array(obj, "attachments");
> > +		*p = '/'; /* bring '/' back */
> > +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
> > +	} else if (typeflag == FTW_DP) {
> > +		;
> > +	} else {
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static bool fill_from_attachments(int idirfd, struct json_t *tests)
> > +{
> > +	char attname[32];
> > +	int attdirfd;
> > +	DIR *currdir;
> > +	int ret;
> > +
> > +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
> > +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> > +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
> > +		return false;
> > +	}
> > +
> > +	currdir = opendir(".");
> > +	fchdir(attdirfd);
> > +
> > +	/*
> > +	 * ftw doesn't support passing user data so *tests has to be
> > +	 * set to some global for being visible in callback function.
> > +	 * As results.json is not processed in multiple threads it is
> > +	 * not a big problem.
> > +	 */
> > +	tmp_tests = tests;
> > +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
> 
> I think another option is to use fts(3)? Since it is a streaming API,
> you can keep the state (i.e. the current json object) as a local
> variable and update as you walk the tree.

CI folks want minimize changes in results.json, so according to above
I would keep everything in flat attachments array.

> 
> It seems it is not POSIX though.  Not sure if that's a real issue for
> IGT, since stuff in IGT are supposed to run on Linux, right?

And Android if I'm not wrong.

> 
> Thinking back, I guess it could fts(3) could even be used for the
> recursive removal.

Question - do we really need this? I can live with ugly static
json at cost of simplicity especially this is only result generator
which likely won't be touched by next months/years...

For attachments case imo allowing recursive creation from hooks scripts
is an overkill.

--
Zbigniew

> 
> --
> Gustavo Sousa
> 
> > +	fchdir(dirfd(currdir));
> > +
> > +	return ret ? false : true;
> > +}
> > +
> >  static const char *result_from_exitcode(int exitcode)
> >  {
> >  	switch (exitcode) {
> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
> >  	}
> >  
> > +	if (!fill_from_attachments(dirfd, results->tests))
> > +		fprintf(stderr, "Error parsing attachments directory\n");
> > +
> >  	override_results(entry->binary, &subtests, results->tests);
> >  	prune_subtests(settings, entry, &subtests, results->tests);
> >  
> > -- 
> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-14 20:33   ` Gustavo Sousa
@ 2026-04-15  8:23     ` Zbigniew Kempczyński
  2026-04-15 12:51       ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15  8:23 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Tue, Apr 14, 2026 at 05:33:08PM -0300, Gustavo Sousa wrote:
> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> 
> > We need to explicitly extract guc logs for failed tests so add hook
> > script which does it after subtest/dynsubtest execution. As copying to
> > attachments takes a lot of time do it only for failing subtests.
> >
> > Adding this hook script to CI will extend execution time much and
> > using allowlist is necessary. Instead of allowlist argument in the
> > runner (previous attempt) now script filters such list on its own and
> > decides when to move forward and do some post-test actions. Such
> > approach is more flexible but moves decision to script what causes
> > it is more prone buggy.
> >
> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> > ---
> > v2: install hook to datadir/hooks
> > v3: migrate allowlist from runner to script
> > ---
> >  scripts/hooks/guc_copy.allowlist  |  2 ++
> >  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
> >  scripts/meson.build               |  3 ++
> >  3 files changed, 52 insertions(+)
> >  create mode 100644 scripts/hooks/guc_copy.allowlist
> >  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
> >
> > diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
> > new file mode 100644
> > index 0000000000..04cb3f8298
> > --- /dev/null
> > +++ b/scripts/hooks/guc_copy.allowlist
> 
> Do we want really want the allowlist to be part distributed with IGT? I
> think we should default it to no allowlist and then CI (or whoever is
> using the hook) defines it if that's desired.

I think we want this allowlist in igt. If there's a test which requires
to copy guc logs due to failure developer who will analyze this can
change allowlist without requesting that from CI folks. We already have
blocklist management in igt source and moving this allowlist management
to CI would split this resposibility. I would keep such management in
one place - is igt source code good place for this - I'm not sure, but
at the moment it's there.

> 
> > @@ -0,0 +1,2 @@
> > +igt@xe_compute@compute-square
> > +igt@xe_exec_basic@once-basic@ccs0
> > diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
> > new file mode 100755
> > index 0000000000..595cf5205e
> > --- /dev/null
> > +++ b/scripts/hooks/guc_copy_on_fail.sh
> 
> Maybe guc_log_on_fail.sh? I think it is more descriptive than
> guc_copy_*, since the latter is a bit vague about what is being copied.

I think copy_guc_log_on_fail.sh would describe its intent better.

> 
> > @@ -0,0 +1,47 @@
> > +#!/bin/bash
> > +
> > +# Hook script for copying guc.log.
> > +# Suggested usage with:
> > +# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
> > +
> > +# Copy only for failed subtests as this is time-consuming
> > +if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
> > +	exit 0
> > +fi
> > +
> > +# Process and copy guc logs only for those specified in allowlist
> > +ALLOWLIST="guc_copy.allowlist"
> > +scriptdir=$(dirname $(realpath $0))
> 
> It is safer to use "$0" above.

Fix me if I'm wrong but $0 won't contain absolute path if script
was executed using relative path like "./scripts/xyz.sh"

> 
> > +
> > +if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
> > +	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
> > +	exit 0
> > +fi
> 
> Well, we could allow the hook user to define the output and default it
> to "$IGT_RUNNER_ATTACHMENTS_DIR/guc_log" if not passed and
> $IGT_RUNNER_ATTACHMENTS_DIR is defined.  Otherwise, we should error out
> IMO (i.e. exit 1).

Ok, in case of missing above enviroment exit with -1 makes sense.

> 
> As an example, someone could be calling a single test binary directly
> and want to use this hook.

If standalone test wants to execute hook script which was designed to
use within runner it should be executed with proper envs set apriori
its execution.

I would like to minimize number of envs passed to scripts from the
runner - IGT_RUNNER_ATTACHMENTS_DIR should be single mandatory
which would point out the script where to write. And single optional
mentioned below - IGT_HOOK_ALLOWLIST_DIR in which script could look
for allowlist. I didn't set it in the runner because I don't know
the allowlist path (this will be know after installing and as DESTDIR=
might be used we can't say from the runner perspective where it will
be). Assuming script and allowlist will land in same directory (as
currently is set in meson) finding it (dirname/realpath) is possible
within the script regardless it was installed.

> 
> We could do some simple argument parsing here or, to make it simpler,
> establish that IGT_HOOKS_GUC_LOG_DEST would be such an input variable
> (and document it in the doc comment at the start of the script).

Multiplying environment is imo bad idea.

> 
> > +
> > +cd "$IGT_RUNNER_ATTACHMENTS_DIR"
> > +
> > +# Look for allowlist in following places:
> > +# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
> > +# 2. Try in <scriptdir>
> > +
> > +if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
> > +	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
> > +else
> > +	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
> > +fi
> 
> I would just receive the allowlist path from CLI args or, to make it
> simpler, from an environment like IGT_HOOKS_GUC_LOG_ALLOWLIST; and I
> think we should default to not using any allowlist if none was passed.

That's good idea - if script would receive optional arg which is
filename it may use it. I'll add this to copy guc log script.

> 
> > +
> > +if [ ! -e "${ALLOWLIST_PATH}" ]; then
> > +	exit 0
> > +fi
> > +
> > +STNAME="${IGT_HOOK_TEST_FULLNAME}"
> > +echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
> > +if [ $? -ne 0 ]; then
> > +	exit 0
> > +fi
> 
> This can simplified with:
> 
>      if ! echo "$IGT_HOOK_TEST_FULLNAME" | grep -q -f "$ALLOWLIST_PATH"; then
>         exit 0;
>      fi
> 
> > +
> > +for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do
> 
> Suggestion: use $(cd /sys/kernel/debug/dri && find -name guc_log)...
> 
> > +	attout=$(echo ${log:23} | sed -e 's/\//_/g')
> 
> ...and then here we don't need this line...
> 
> > +	mkdir -p "${STNAME}"
> > +	cp "$log" "${STNAME}/${attout}"
> 
> ...and here we can simply do: cp "$log" "$STNAME/${log////_}".

Will apply above in v4.

> 
> One issue with the find command above is that we could potentially
> collect GuC log for other device (not the one under test).  I know that
> IGT supports selecting a device via the environment variable
> IGT_DEVICE.  I wonder if we should make it set an environment for the
> device under test; we could use a different variable name to avoid
> issues with the existing one.

Good point. Question is - how to pass more than one PCIID in multigpu
scenarios? For single card it is simple, we can set IGT_HOOK_LAST_PCIID=
for each opened device. I'll take a look to this and share my thoughts.

Thanks for the review.
--
Zbigniew

> 
> --
> Gustavo Sousa
> 
> > +done
> > diff --git a/scripts/meson.build b/scripts/meson.build
> > index 6e64065c5e..2ce961898d 100644
> > --- a/scripts/meson.build
> > +++ b/scripts/meson.build
> > @@ -15,3 +15,6 @@ endif
> >  igt_doc_script = find_program('igt_doc.py', required : build_testplan)
> >  gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
> >  generate_iga64_codes = find_program('generate_iga64_codes')
> > +
> > +install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
> > +install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
> > -- 
> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-15  6:31     ` Zbigniew Kempczyński
@ 2026-04-15 12:16       ` Gustavo Sousa
  2026-04-15 16:09         ` Zbigniew Kempczyński
  0 siblings, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-15 12:16 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Tue, Apr 14, 2026 at 06:39:28PM -0300, Gustavo Sousa wrote:
>> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> 
>> > Add list of filenames which were created by hooks in attachments directory
>> > (like GuC log copy) to results.json for allow presenting it in CI.
>> >
>> > Due to lack of userdata pointer in nftw() implementation main json
>> > object is passed via temporary static variable. It shouldn't be the
>> > problem because results.json is created in single thread. This change
>> > is not too elegant but allows to minimize the code change and is
>> > much easier to read comparing to recursive readdir().
>> >
>> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>> > Cc: Ryszard Knop <ryszard.knop@intel.com>
>> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
>> > ---
>> >  runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
>> >  1 file changed, 63 insertions(+)
>> >
>> > diff --git a/runner/resultgen.c b/runner/resultgen.c
>> > index f8459385c3..d37f01a433 100644
>> > --- a/runner/resultgen.c
>> > +++ b/runner/resultgen.c
>> > @@ -1,11 +1,14 @@
>> >  #include <assert.h>
>> >  #include <ctype.h>
>> > +#include <dirent.h>
>> >  #include <fcntl.h>
>> > +#include <ftw.h>
>> >  #include <inttypes.h>
>> >  #include <stdio.h>
>> >  #include <string.h>
>> >  #include <sys/mman.h>
>> >  #include <sys/stat.h>
>> > +#include <sys/types.h>
>> >  #include <unistd.h>
>> >  
>> >  #include <jansson.h>
>> > @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
>> >  	return true;
>> >  }
>> >  
>> > +struct json_t *tmp_tests;
>> > +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
>> > +				int typeflag, struct FTW *ftwbuf)
>> > +{
>> > +	struct json_t *obj = NULL, *attobj = NULL;
>> > +	(void)sb;
>> > +	(void)ftwbuf;
>> > +
>> > +	if (typeflag == FTW_F) {
>> > +		char *p;
>> > +
>> > +		p = strstr(fpath + 2, "/");
>> > +		if (!p)
>> > +			return -1;
>> > +		*p = '\0'; /* temporary for acquiring the piglit name */
>> > +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
>> 
>> For this to be trully recursive, I think we should create the JSON
>> object in the FTW_DP case.
>
> What for? Imo attachments array for test/subtest which contains
> relative paths from test/subtest is enough. I see no value by adding
> recursive arrays apart of increasing complexity to the code. Be aware CI has
> to present these attachments as well, so more we complicate results.json
> more work will be on CI side to alter javascript.
>
>> 
>> > +		attobj = get_or_create_json_array(obj, "attachments");
>> > +		*p = '/'; /* bring '/' back */
>> > +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
>> > +	} else if (typeflag == FTW_DP) {
>> > +		;
>> > +	} else {
>> > +		return -1;
>> > +	}
>> > +
>> > +	return 0;
>> > +}
>> > +
>> > +static bool fill_from_attachments(int idirfd, struct json_t *tests)
>> > +{
>> > +	char attname[32];
>> > +	int attdirfd;
>> > +	DIR *currdir;
>> > +	int ret;
>> > +
>> > +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
>> > +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
>> > +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
>> > +		return false;
>> > +	}
>> > +
>> > +	currdir = opendir(".");
>> > +	fchdir(attdirfd);
>> > +
>> > +	/*
>> > +	 * ftw doesn't support passing user data so *tests has to be
>> > +	 * set to some global for being visible in callback function.
>> > +	 * As results.json is not processed in multiple threads it is
>> > +	 * not a big problem.
>> > +	 */
>> > +	tmp_tests = tests;
>> > +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
>> 
>> I think another option is to use fts(3)? Since it is a streaming API,
>> you can keep the state (i.e. the current json object) as a local
>> variable and update as you walk the tree.
>
> CI folks want minimize changes in results.json, so according to above
> I would keep everything in flat attachments array.
>
>> 
>> It seems it is not POSIX though.  Not sure if that's a real issue for
>> IGT, since stuff in IGT are supposed to run on Linux, right?
>
> And Android if I'm not wrong.

That's Linux as well, no?  Perhaps just need to have a sanity check to
see if those functions are also available there.

>
>> 
>> Thinking back, I guess it could fts(3) could even be used for the
>> recursive removal.
>
> Question - do we really need this? I can live with ugly static
> json at cost of simplicity especially this is only result generator
> which likely won't be touched by next months/years...

I would say: if the right tool is available for the job, why not using
it?

Not going to block on this though...

>
> For attachments case imo allowing recursive creation from hooks scripts
> is an overkill.

The hook mechanism is not something created for exclusive use by CI. It
is a tool for developers to use are they see fit.  That was my original
intention when I first developed the hooks infrastructure.

I don't like the fact that we are making assumptions of how the hooks
will behave here.

If CI wants a flat structure, that's fine: let CI provide hooks that
generate files in a flat hierarchy.  I just think that it is not right
to assume that all hooks will behave like that.

--
Gustavo Sousa

>
> --
> Zbigniew
>
>> 
>> --
>> Gustavo Sousa
>> 
>> > +	fchdir(dirfd(currdir));
>> > +
>> > +	return ret ? false : true;
>> > +}
>> > +
>> >  static const char *result_from_exitcode(int exitcode)
>> >  {
>> >  	switch (exitcode) {
>> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
>> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
>> >  	}
>> >  
>> > +	if (!fill_from_attachments(dirfd, results->tests))
>> > +		fprintf(stderr, "Error parsing attachments directory\n");
>> > +
>> >  	override_results(entry->binary, &subtests, results->tests);
>> >  	prune_subtests(settings, entry, &subtests, results->tests);
>> >  
>> > -- 
>> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-15  8:23     ` Zbigniew Kempczyński
@ 2026-04-15 12:51       ` Gustavo Sousa
  2026-04-16 18:44         ` Zbigniew Kempczyński
  0 siblings, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-15 12:51 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Tue, Apr 14, 2026 at 05:33:08PM -0300, Gustavo Sousa wrote:
>> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> 
>> > We need to explicitly extract guc logs for failed tests so add hook
>> > script which does it after subtest/dynsubtest execution. As copying to
>> > attachments takes a lot of time do it only for failing subtests.
>> >
>> > Adding this hook script to CI will extend execution time much and
>> > using allowlist is necessary. Instead of allowlist argument in the
>> > runner (previous attempt) now script filters such list on its own and
>> > decides when to move forward and do some post-test actions. Such
>> > approach is more flexible but moves decision to script what causes
>> > it is more prone buggy.
>> >
>> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>> > Cc: Ryszard Knop <ryszard.knop@intel.com>
>> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
>> > ---
>> > v2: install hook to datadir/hooks
>> > v3: migrate allowlist from runner to script
>> > ---
>> >  scripts/hooks/guc_copy.allowlist  |  2 ++
>> >  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
>> >  scripts/meson.build               |  3 ++
>> >  3 files changed, 52 insertions(+)
>> >  create mode 100644 scripts/hooks/guc_copy.allowlist
>> >  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
>> >
>> > diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
>> > new file mode 100644
>> > index 0000000000..04cb3f8298
>> > --- /dev/null
>> > +++ b/scripts/hooks/guc_copy.allowlist
>> 
>> Do we want really want the allowlist to be part distributed with IGT? I
>> think we should default it to no allowlist and then CI (or whoever is
>> using the hook) defines it if that's desired.
>
> I think we want this allowlist in igt. If there's a test which requires
> to copy guc logs due to failure developer who will analyze this can
> change allowlist without requesting that from CI folks. We already have
> blocklist management in igt source and moving this allowlist management
> to CI would split this resposibility. I would keep such management in
> one place - is igt source code good place for this - I'm not sure, but
> at the moment it's there.

Understood.  Yeah, I guess it is fine to keep CI-managed allowlist in
IGT as well, then.

Since we have CI blocklists in the tests/intel-ci folder, maybe that's
where this hook's allowlist should live as well?  Maybe in the future we
could move intel-ci to belong to the root of the project, since it would
contain more than testlists.

Now, I don't think executables generated by IGT apply the blocklists
automatically, but CI passes the blocklists as argument as part of their
workflow, right?

If that's the case, I think it would make sense for the hook to do the
same.  In other words, my suggestion is that we can have a CI-managed
allowlist file, but not use it by default -- CI would pass it when using
the hook.

>
>> 
>> > @@ -0,0 +1,2 @@
>> > +igt@xe_compute@compute-square
>> > +igt@xe_exec_basic@once-basic@ccs0
>> > diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
>> > new file mode 100755
>> > index 0000000000..595cf5205e
>> > --- /dev/null
>> > +++ b/scripts/hooks/guc_copy_on_fail.sh
>> 
>> Maybe guc_log_on_fail.sh? I think it is more descriptive than
>> guc_copy_*, since the latter is a bit vague about what is being copied.
>
> I think copy_guc_log_on_fail.sh would describe its intent better.

Ack.

>
>> 
>> > @@ -0,0 +1,47 @@
>> > +#!/bin/bash
>> > +
>> > +# Hook script for copying guc.log.
>> > +# Suggested usage with:
>> > +# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
>> > +
>> > +# Copy only for failed subtests as this is time-consuming
>> > +if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
>> > +	exit 0
>> > +fi
>> > +
>> > +# Process and copy guc logs only for those specified in allowlist
>> > +ALLOWLIST="guc_copy.allowlist"
>> > +scriptdir=$(dirname $(realpath $0))
>> 
>> It is safer to use "$0" above.
>
> Fix me if I'm wrong but $0 won't contain absolute path if script
> was executed using relative path like "./scripts/xyz.sh"

I mean to use "$0" (rather than $0) as argument of realpath.  Actually,
I think the safest would be:

  scriptdir=$(dirname "$(realpath "$0")")

>
>> 
>> > +
>> > +if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
>> > +	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
>> > +	exit 0
>> > +fi
>> 
>> Well, we could allow the hook user to define the output and default it
>> to "$IGT_RUNNER_ATTACHMENTS_DIR/guc_log" if not passed and
>> $IGT_RUNNER_ATTACHMENTS_DIR is defined.  Otherwise, we should error out
>> IMO (i.e. exit 1).
>
> Ok, in case of missing above enviroment exit with -1 makes sense.
>
>> 
>> As an example, someone could be calling a single test binary directly
>> and want to use this hook.
>
> If standalone test wants to execute hook script which was designed to
> use within runner it should be executed with proper envs set apriori
> its execution.
>
> I would like to minimize number of envs passed to scripts from the
> runner - IGT_RUNNER_ATTACHMENTS_DIR should be single mandatory
> which would point out the script where to write. And single optional
> mentioned below - IGT_HOOK_ALLOWLIST_DIR in which script could look
> for allowlist. I didn't set it in the runner because I don't know
> the allowlist path (this will be know after installing and as DESTDIR=
> might be used we can't say from the runner perspective where it will
> be). Assuming script and allowlist will land in same directory (as
> currently is set in meson) finding it (dirname/realpath) is possible
> within the script regardless it was installed.
>
>> 
>> We could do some simple argument parsing here or, to make it simpler,
>> establish that IGT_HOOKS_GUC_LOG_DEST would be such an input variable
>> (and document it in the doc comment at the start of the script).
>
> Multiplying environment is imo bad idea.
>

I think the hook should be a standalone tool that could be used for
either single tests or in the igt_runner environment.  I think we
should make it easier for both cases, meaning to have a simple way of
the hook user to define the necesary parameters (destination dir and
allowlist file) and make it define sensible defaults when it detects
it is running in a igt_runner environment.

If you prefer that the hook should be specific for the igt_runner
environment, then I guess it is fine to avoid the extra work I'm
suggesting.  We could revisit this in the future if we find users trying
to use it with standalone tests.

>> 
>> > +
>> > +cd "$IGT_RUNNER_ATTACHMENTS_DIR"
>> > +
>> > +# Look for allowlist in following places:
>> > +# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
>> > +# 2. Try in <scriptdir>
>> > +
>> > +if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
>> > +	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
>> > +else
>> > +	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
>> > +fi
>> 
>> I would just receive the allowlist path from CLI args or, to make it
>> simpler, from an environment like IGT_HOOKS_GUC_LOG_ALLOWLIST; and I
>> think we should default to not using any allowlist if none was passed.
>
> That's good idea - if script would receive optional arg which is
> filename it may use it. I'll add this to copy guc log script.
>
>> 
>> > +
>> > +if [ ! -e "${ALLOWLIST_PATH}" ]; then
>> > +	exit 0
>> > +fi
>> > +
>> > +STNAME="${IGT_HOOK_TEST_FULLNAME}"
>> > +echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
>> > +if [ $? -ne 0 ]; then
>> > +	exit 0
>> > +fi
>> 
>> This can simplified with:
>> 
>>      if ! echo "$IGT_HOOK_TEST_FULLNAME" | grep -q -f "$ALLOWLIST_PATH"; then
>>         exit 0;
>>      fi
>> 
>> > +
>> > +for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do
>> 
>> Suggestion: use $(cd /sys/kernel/debug/dri && find -name guc_log)...
>> 
>> > +	attout=$(echo ${log:23} | sed -e 's/\//_/g')
>> 
>> ...and then here we don't need this line...
>> 
>> > +	mkdir -p "${STNAME}"
>> > +	cp "$log" "${STNAME}/${attout}"
>> 
>> ...and here we can simply do: cp "$log" "$STNAME/${log////_}".
>
> Will apply above in v4.
>
>> 
>> One issue with the find command above is that we could potentially
>> collect GuC log for other device (not the one under test).  I know that
>> IGT supports selecting a device via the environment variable
>> IGT_DEVICE.  I wonder if we should make it set an environment for the
>> device under test; we could use a different variable name to avoid
>> issues with the existing one.
>
> Good point. Question is - how to pass more than one PCIID in multigpu
> scenarios? For single card it is simple, we can set IGT_HOOK_LAST_PCIID=
> for each opened device. I'll take a look to this and share my thoughts.

Ah, interesting.  I wasn't aware of this possibility; so we do have
tests that work on multiple devices?

Yeah, maybe a variable that uses some sort of separator.  I guess this
needs a separate discussion and we can keep the hook looking for
guc_log files for any available device for now?  We could add a comment
noting this behavior.

--
Gustavo Sousa

>
> Thanks for the review.
> --
> Zbigniew
>
>> 
>> --
>> Gustavo Sousa
>> 
>> > +done
>> > diff --git a/scripts/meson.build b/scripts/meson.build
>> > index 6e64065c5e..2ce961898d 100644
>> > --- a/scripts/meson.build
>> > +++ b/scripts/meson.build
>> > @@ -15,3 +15,6 @@ endif
>> >  igt_doc_script = find_program('igt_doc.py', required : build_testplan)
>> >  gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
>> >  generate_iga64_codes = find_program('generate_iga64_codes')
>> > +
>> > +install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
>> > +install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
>> > -- 
>> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-15  5:34     ` Zbigniew Kempczyński
@ 2026-04-15 13:48       ` Gustavo Sousa
  2026-04-15 16:37         ` Zbigniew Kempczyński
  0 siblings, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-15 13:48 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Tue, Apr 14, 2026 at 04:27:48PM -0300, Gustavo Sousa wrote:
>> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> 
>> > Results parsing is currently limited to few predefined files.
>> >
>> > Create "attachments" directory and export full path of created directory
>> > to be used within hooks. From now on environment variable
>> > IGT_RUNNER_ATTACHMENTS_DIR become visible when igt_runner is used
>> > to execute tests. This env contains directory where subtests/dynsubtests
>> > may write auxiliary files which finally be included in results.json.
>> >
>> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>> > Cc: Ryszard Knop <ryszard.knop@intel.com>
>> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
>> > ---
>> > v2: simplify attachment dirname concatenation (Kamil)
>> >     remove files in attachments dir when overwrite is set (Kamil)
>> > v3: unify 'attdir*' variables (Krzysztof)
>> >     do recursive removal in attachments directories (Gustavo)
>> > ---
>> >  lib/igt_hook.c    |  4 +++
>> >  runner/executor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++--
>> >  runner/executor.h |  2 ++
>> >  3 files changed, 78 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/lib/igt_hook.c b/lib/igt_hook.c
>> > index f86ed56f72..b8f25b6c7a 100644
>> > --- a/lib/igt_hook.c
>> > +++ b/lib/igt_hook.c
>> > @@ -518,5 +518,9 @@ available to the command:\n\
>> >  \n\
>> >  Note that %s can be passed multiple times. Each descriptor is evaluated in turn\n\
>> >  when matching events and running hook commands.\n\
>> > +\n\
>> > +When executed by the igt_runner, environment IGT_RUNNER_ATTACHMENTS_DIR\n\
>> > +is passed additionally to the hook script. It contains directory where\n\
>> > +script may write additional attachments like guc logs, etc.\n\
>> >  ", option_name);
>> >  }
>> > diff --git a/runner/executor.c b/runner/executor.c
>> > index 1485b59d1f..af39b12aea 100644
>> > --- a/runner/executor.c
>> > +++ b/runner/executor.c
>> > @@ -1,6 +1,7 @@
>> >  #include <ctype.h>
>> >  #include <errno.h>
>> >  #include <fcntl.h>
>> > +#include <ftw.h>
>> >  #ifdef ANDROID
>> >  #include "android/glib.h"
>> >  #else
>> > @@ -1779,17 +1780,22 @@ static int execute_next_entry(struct execute_state *state,
>> >  	int errpipe[2] = { -1, -1 };
>> >  	int socket[2] = { -1, -1 };
>> >  	int outfd, errfd, socketfd;
>> > -	char name[32];
>> > +	char name[32], attname[32];
>> > +	char attdirname[PATH_MAX];
>> >  	pid_t child;
>> >  	int result;
>> >  	size_t idx = state->next;
>> >  
>> >  	snprintf(name, sizeof(name), "%zd", idx);
>> > +	snprintf(attname, sizeof(attname), "%zd/%s", idx, DIR_ATTACHMENTS);
>> >  	mkdirat(resdirfd, name, 0777);
>> > +	mkdirat(resdirfd, attname, 0777);
>> >  	if ((idirfd = openat(resdirfd, name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
>> >  		errf("Error accessing individual test result directory\n");
>> >  		return -1;
>> >  	}
>> > +	snprintf(attdirname, sizeof(attdirname), "%s/%s",
>> > +		 settings->results_path, attname);
>> >  
>> >  	if (!open_output_files(idirfd, outputs, true)) {
>> >  		errf("Error opening output files\n");
>> > @@ -1870,6 +1876,7 @@ static int execute_next_entry(struct execute_state *state,
>> >  			setenv("IGT_RUNNER_SOCKET_FD", envstring, 1);
>> >  		}
>> >  		setenv("IGT_SENTINEL_ON_STDERR", "1", 1);
>> > +		setenv("IGT_RUNNER_ATTACHMENTS_DIR", attdirname, 1);
>> >  
>> >  		execute_test_process(outfd, errfd, socketfd, settings, entry);
>> >  		/* unreachable */
>> > @@ -1948,9 +1955,61 @@ static int remove_file(int dirfd, const char *name)
>> >  	return unlinkat(dirfd, name, 0) && errno != ENOENT;
>> >  }
>> >  
>> > +static int ftw_attachment_removal(const char *fpath, const struct stat *sb,
>> > +				  int typeflag, struct FTW *ftwbuf)
>> > +{
>> > +	(void)sb;
>> > +	(void)ftwbuf;
>> 
>> I was able to compile without warnings after dropping this.  Is there a
>> reason to keep them here?
>
> I'm trying to keep code I write clean according to warnings. We have
> '-Wno-unused-parameter' in meson.build so above lines could be dropped.
> But if someone will decide to clean the code I won't give him/her more
> work. And imo this is in good taste to annotate unused arguments.
>
>> 
>> > +
>> > +	if (typeflag == FTW_F) {
>> > +		if (unlink(fpath)) {
>> > +			errf("Cannot remove file %s\n", fpath);
>> 
>> Maybe append strerror(errno) to the message here?
>
> Yes, why not.
>
>> 
>> > +			return -1;
>> > +		}
>> > +	} else if (typeflag == FTW_DP) {
>> > +		if (rmdir(fpath)) {
>> > +			errf("Cannot remove directory %s\n", fpath);
>> 
>> Ditto.
>> 
>> > +			return -1;
>> > +		}
>> > +	} else {
>> > +		errf("Cannot remove %s (unsupported file type)\n", fpath);
>> > +		return -1;
>> 
>> I think it would be sensible to drop symbolic links as well (I think it
>> could be handled in the same brace for FTW_F.
>
> I wondered about this, but I would be strict - only files and dirs
> are allowed in the attachments directory. What for user/script would do
> symbolic links there?

Not sure, but I don't see a reason to disallow them.  We can't predict
what a user hook will do, so I would be in favor of being more flexible
when we can.

>
>> 
>> > +	}
>> 
>> I think this would look nicer if it was handled with a "switch"
>> statement.
>
> Agree, switch with default will look better in this case. I'll
> replace if's to switch in v4.
>
>> 
>> > +
>> > +	return 0;
>> > +}
>> > +
>> > +static bool clear_attachments_dir_recursively(int attdirfd)
>> > +{
>> > +	char attdirname[PATH_MAX];
>> > +	DIR *currdir;
>> > +	int ret;
>> > +
>> > +	currdir = opendir(".");
>> 
>> Why do we need this call?
>
> nftw() requires path, not fd so I have to ensure I leave working
> directory intact when I quit the function. I don't know any method
> apart of fchdir/getcwd() to get dirname I would like to pass to
> nftw(). And I won't assume I know where's current working dir.

Ah, I overlooked the fact that currdir is used to get back to the
directory at the end of the function. My bad.

That said, I do feel like we are doing a bit too much here and passing
the path directly would make it simpler (that is, if we were to continue
to use a separate clear_attachments_dir_recursively() function, as
opposed to my suggestion below).

>
>> 
>> > +	fchdir(attdirfd);
>> > +	getcwd(attdirname, sizeof(attdirname));
>> > +
>> > +	/* Sanity check we're in attachments directory structure */
>> > +	if (!strstr(attdirname, DIR_ATTACHMENTS)) {
>> > +		errf("Cowardly refusing removing in directory which is not "
>> > +		     "attachments directory [currdir: %s]!\n", attdirname);
>> > +		ret = -1;
>> > +		goto out;
>> > +	}
>> 
>> This function is static and only called for DIR_ATTACHMENTS.  I believe
>> this check is unnecessary.
>
> Assuming no bug is here you're right, but I would like to do double check
> directory content I want to remove is really I expect to.

I think this check would make sense if things were more complex and
would make it hard to predict how this function would be called.  I
don't think that's the case here, though: this is a simple case where
there is only one call site for this function and it is for the
DIR_ATTACHMENTS.

I even think, as mentioned in an earlier reply, that this function could
be avoided completely, but I won't block on that.

>
>> 
>> > +
>> > +	ret = nftw(attdirname, ftw_attachment_removal, 4, FTW_PHYS | FTW_DEPTH);
>> > +
>> > +out:
>> > +	fchdir(dirfd(currdir));
>> > +	closedir(currdir);
>> > +
>> > +	return ret ? false : true;
>> > +}
>> > +
>> >  static bool clear_test_result_directory(int dirfd)
>> 
>> I think we need to have the path to the test result dir passed as
>> argument here so that we can build attdirname without having the change
>> dir + get cwd dance.
>
> I didn't want to rewrite clear_old_results() function. Current code
> uses mostly fd's and only place where I really need path is nftw().
> I will rewrite to passing paths if you insist but personally I wouldn't
> do this.

I think this scenario justifies rewriting clear_old_results() to pass
the path as well.  We are doing extra steps -- creating attdirfd and
then, inside clear_attachments_dir_recursively(), all that handling of
fds -- for no real benefit besides conforming to a "fd as argument"
standard IMO.

>
>> 
>> >  {
>> > -	int i;
>> > +	int i, attdirfd;
>> > +	int ret = true;
>> 
>> I guess we don't need this ret variable. If the removal of the
>> attachments directory fails, we can just print an error message and
>> return false.
>
> Ok.
>
>> 
>> >  
>> >  	for (i = 0; i < _F_LAST; i++) {
>> >  		if (remove_file(dirfd, filenames[i])) {
>> > @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
>> >  		}
>> >  	}
>> >  
>> > -	return true;
>> > +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
>> > +		errf("Cannot open attachments directory\n");
>> > +		return false;
>> > +	}
>> > +
>> > +	ret = clear_attachments_dir_recursively(attdirfd);
>> > +	if (!ret)
>> > +		errf("Cannot clear attachments dir recursively\n");
>> 
>> Why not simply call nftw() directly from here? I don't see much value in
>> having the function clear_attachments_dir_recursively().
>
> I created a separate function because I like dividing logical tasks
> to separate functions. I can unfold this function here if you think
> this will be better.

I can live with the separate function.  I just think dropping it greatly
simplifies the current code.  Your call.

--
Gustavo Sousa

>
> --
> Zbigniew
>
>> 
>> --
>> Gustavo Sousa
>> 
>> > +
>> > +	return ret;
>> >  }
>> >  
>> >  static bool clear_old_results(char *path)
>> > @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
>> >  			close(dirfd);
>> >  			return false;
>> >  		}
>> > +
>> >  		close(resdirfd);
>> >  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
>> >  			errf("Warning: Result directory %s contains extra files\n",
>> > diff --git a/runner/executor.h b/runner/executor.h
>> > index 3b1cabcf55..bc6ac80dc4 100644
>> > --- a/runner/executor.h
>> > +++ b/runner/executor.h
>> > @@ -25,6 +25,8 @@ enum {
>> >  	_F_LAST,
>> >  };
>> >  
>> > +#define DIR_ATTACHMENTS "attachments"
>> > +
>> >  bool open_output_files(int dirfd, int *fds, bool write);
>> >  bool open_output_files_rdonly(int dirfd, int *fds);
>> >  void close_outputs(int *fds);
>> > -- 
>> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-15 12:16       ` Gustavo Sousa
@ 2026-04-15 16:09         ` Zbigniew Kempczyński
  2026-04-15 16:20           ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15 16:09 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Wed, Apr 15, 2026 at 09:16:33AM -0300, Gustavo Sousa wrote:
> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> 
> > On Tue, Apr 14, 2026 at 06:39:28PM -0300, Gustavo Sousa wrote:
> >> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> >> 
> >> > Add list of filenames which were created by hooks in attachments directory
> >> > (like GuC log copy) to results.json for allow presenting it in CI.
> >> >
> >> > Due to lack of userdata pointer in nftw() implementation main json
> >> > object is passed via temporary static variable. It shouldn't be the
> >> > problem because results.json is created in single thread. This change
> >> > is not too elegant but allows to minimize the code change and is
> >> > much easier to read comparing to recursive readdir().
> >> >
> >> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> >> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> >> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> >> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> >> > ---
> >> >  runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
> >> >  1 file changed, 63 insertions(+)
> >> >
> >> > diff --git a/runner/resultgen.c b/runner/resultgen.c
> >> > index f8459385c3..d37f01a433 100644
> >> > --- a/runner/resultgen.c
> >> > +++ b/runner/resultgen.c
> >> > @@ -1,11 +1,14 @@
> >> >  #include <assert.h>
> >> >  #include <ctype.h>
> >> > +#include <dirent.h>
> >> >  #include <fcntl.h>
> >> > +#include <ftw.h>
> >> >  #include <inttypes.h>
> >> >  #include <stdio.h>
> >> >  #include <string.h>
> >> >  #include <sys/mman.h>
> >> >  #include <sys/stat.h>
> >> > +#include <sys/types.h>
> >> >  #include <unistd.h>
> >> >  
> >> >  #include <jansson.h>
> >> > @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
> >> >  	return true;
> >> >  }
> >> >  
> >> > +struct json_t *tmp_tests;
> >> > +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
> >> > +				int typeflag, struct FTW *ftwbuf)
> >> > +{
> >> > +	struct json_t *obj = NULL, *attobj = NULL;
> >> > +	(void)sb;
> >> > +	(void)ftwbuf;
> >> > +
> >> > +	if (typeflag == FTW_F) {
> >> > +		char *p;
> >> > +
> >> > +		p = strstr(fpath + 2, "/");
> >> > +		if (!p)
> >> > +			return -1;
> >> > +		*p = '\0'; /* temporary for acquiring the piglit name */
> >> > +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
> >> 
> >> For this to be trully recursive, I think we should create the JSON
> >> object in the FTW_DP case.
> >
> > What for? Imo attachments array for test/subtest which contains
> > relative paths from test/subtest is enough. I see no value by adding
> > recursive arrays apart of increasing complexity to the code. Be aware CI has
> > to present these attachments as well, so more we complicate results.json
> > more work will be on CI side to alter javascript.
> >
> >> 
> >> > +		attobj = get_or_create_json_array(obj, "attachments");
> >> > +		*p = '/'; /* bring '/' back */
> >> > +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
> >> > +	} else if (typeflag == FTW_DP) {
> >> > +		;
> >> > +	} else {
> >> > +		return -1;
> >> > +	}
> >> > +
> >> > +	return 0;
> >> > +}
> >> > +
> >> > +static bool fill_from_attachments(int idirfd, struct json_t *tests)
> >> > +{
> >> > +	char attname[32];
> >> > +	int attdirfd;
> >> > +	DIR *currdir;
> >> > +	int ret;
> >> > +
> >> > +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
> >> > +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> >> > +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
> >> > +		return false;
> >> > +	}
> >> > +
> >> > +	currdir = opendir(".");
> >> > +	fchdir(attdirfd);
> >> > +
> >> > +	/*
> >> > +	 * ftw doesn't support passing user data so *tests has to be
> >> > +	 * set to some global for being visible in callback function.
> >> > +	 * As results.json is not processed in multiple threads it is
> >> > +	 * not a big problem.
> >> > +	 */
> >> > +	tmp_tests = tests;
> >> > +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
> >> 
> >> I think another option is to use fts(3)? Since it is a streaming API,
> >> you can keep the state (i.e. the current json object) as a local
> >> variable and update as you walk the tree.
> >
> > CI folks want minimize changes in results.json, so according to above
> > I would keep everything in flat attachments array.
> >
> >> 
> >> It seems it is not POSIX though.  Not sure if that's a real issue for
> >> IGT, since stuff in IGT are supposed to run on Linux, right?
> >
> > And Android if I'm not wrong.
> 
> That's Linux as well, no?  Perhaps just need to have a sanity check to
> see if those functions are also available there.
> 
> >
> >> 
> >> Thinking back, I guess it could fts(3) could even be used for the
> >> recursive removal.
> >
> > Question - do we really need this? I can live with ugly static
> > json at cost of simplicity especially this is only result generator
> > which likely won't be touched by next months/years...
> 
> I would say: if the right tool is available for the job, why not using
> it?
> 
> Not going to block on this though...
> 
> >
> > For attachments case imo allowing recursive creation from hooks scripts
> > is an overkill.
> 
> The hook mechanism is not something created for exclusive use by CI. It
> is a tool for developers to use are they see fit.  That was my original
> intention when I first developed the hooks infrastructure.
> 
> I don't like the fact that we are making assumptions of how the hooks
> will behave here.
> 
> If CI wants a flat structure, that's fine: let CI provide hooks that
> generate files in a flat hierarchy.  I just think that it is not right
> to assume that all hooks will behave like that.

Executing hooks out of igt_runner won't provide results.json, right?
So all that recursive removal / etc doesn't makes sense when you execute
tests standalone.

--
Zbigniew


> 
> --
> Gustavo Sousa
> 
> >
> > --
> > Zbigniew
> >
> >> 
> >> --
> >> Gustavo Sousa
> >> 
> >> > +	fchdir(dirfd(currdir));
> >> > +
> >> > +	return ret ? false : true;
> >> > +}
> >> > +
> >> >  static const char *result_from_exitcode(int exitcode)
> >> >  {
> >> >  	switch (exitcode) {
> >> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
> >> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
> >> >  	}
> >> >  
> >> > +	if (!fill_from_attachments(dirfd, results->tests))
> >> > +		fprintf(stderr, "Error parsing attachments directory\n");
> >> > +
> >> >  	override_results(entry->binary, &subtests, results->tests);
> >> >  	prune_subtests(settings, entry, &subtests, results->tests);
> >> >  
> >> > -- 
> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-15 16:09         ` Zbigniew Kempczyński
@ 2026-04-15 16:20           ` Gustavo Sousa
  2026-04-15 19:56             ` Zbigniew Kempczyński
  0 siblings, 1 reply; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-15 16:20 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Wed, Apr 15, 2026 at 09:16:33AM -0300, Gustavo Sousa wrote:
>> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> 
>> > On Tue, Apr 14, 2026 at 06:39:28PM -0300, Gustavo Sousa wrote:
>> >> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> >> 
>> >> > Add list of filenames which were created by hooks in attachments directory
>> >> > (like GuC log copy) to results.json for allow presenting it in CI.
>> >> >
>> >> > Due to lack of userdata pointer in nftw() implementation main json
>> >> > object is passed via temporary static variable. It shouldn't be the
>> >> > problem because results.json is created in single thread. This change
>> >> > is not too elegant but allows to minimize the code change and is
>> >> > much easier to read comparing to recursive readdir().
>> >> >
>> >> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>> >> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>> >> > Cc: Ryszard Knop <ryszard.knop@intel.com>
>> >> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
>> >> > ---
>> >> >  runner/resultgen.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
>> >> >  1 file changed, 63 insertions(+)
>> >> >
>> >> > diff --git a/runner/resultgen.c b/runner/resultgen.c
>> >> > index f8459385c3..d37f01a433 100644
>> >> > --- a/runner/resultgen.c
>> >> > +++ b/runner/resultgen.c
>> >> > @@ -1,11 +1,14 @@
>> >> >  #include <assert.h>
>> >> >  #include <ctype.h>
>> >> > +#include <dirent.h>
>> >> >  #include <fcntl.h>
>> >> > +#include <ftw.h>
>> >> >  #include <inttypes.h>
>> >> >  #include <stdio.h>
>> >> >  #include <string.h>
>> >> >  #include <sys/mman.h>
>> >> >  #include <sys/stat.h>
>> >> > +#include <sys/types.h>
>> >> >  #include <unistd.h>
>> >> >  
>> >> >  #include <jansson.h>
>> >> > @@ -1156,6 +1159,63 @@ static bool fill_from_dmesg(int fd,
>> >> >  	return true;
>> >> >  }
>> >> >  
>> >> > +struct json_t *tmp_tests;
>> >> > +static int ftw_attachments_list(const char *fpath, const struct stat *sb,
>> >> > +				int typeflag, struct FTW *ftwbuf)
>> >> > +{
>> >> > +	struct json_t *obj = NULL, *attobj = NULL;
>> >> > +	(void)sb;
>> >> > +	(void)ftwbuf;
>> >> > +
>> >> > +	if (typeflag == FTW_F) {
>> >> > +		char *p;
>> >> > +
>> >> > +		p = strstr(fpath + 2, "/");
>> >> > +		if (!p)
>> >> > +			return -1;
>> >> > +		*p = '\0'; /* temporary for acquiring the piglit name */
>> >> > +		obj = get_or_create_json_object(tmp_tests, fpath + 2);
>> >> 
>> >> For this to be trully recursive, I think we should create the JSON
>> >> object in the FTW_DP case.
>> >
>> > What for? Imo attachments array for test/subtest which contains
>> > relative paths from test/subtest is enough. I see no value by adding
>> > recursive arrays apart of increasing complexity to the code. Be aware CI has
>> > to present these attachments as well, so more we complicate results.json
>> > more work will be on CI side to alter javascript.
>> >
>> >> 
>> >> > +		attobj = get_or_create_json_array(obj, "attachments");
>> >> > +		*p = '/'; /* bring '/' back */
>> >> > +		json_array_append_new(attobj, escaped_json_stringn(fpath + 2, strlen(fpath + 2)));
>> >> > +	} else if (typeflag == FTW_DP) {
>> >> > +		;
>> >> > +	} else {
>> >> > +		return -1;
>> >> > +	}
>> >> > +
>> >> > +	return 0;
>> >> > +}
>> >> > +
>> >> > +static bool fill_from_attachments(int idirfd, struct json_t *tests)
>> >> > +{
>> >> > +	char attname[32];
>> >> > +	int attdirfd;
>> >> > +	DIR *currdir;
>> >> > +	int ret;
>> >> > +
>> >> > +	snprintf(attname, sizeof(attname), "%s", DIR_ATTACHMENTS);
>> >> > +	if ((attdirfd = openat(idirfd, attname, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
>> >> > +		fprintf(stderr, "Error opening '%s' dir\n", DIR_ATTACHMENTS);
>> >> > +		return false;
>> >> > +	}
>> >> > +
>> >> > +	currdir = opendir(".");
>> >> > +	fchdir(attdirfd);
>> >> > +
>> >> > +	/*
>> >> > +	 * ftw doesn't support passing user data so *tests has to be
>> >> > +	 * set to some global for being visible in callback function.
>> >> > +	 * As results.json is not processed in multiple threads it is
>> >> > +	 * not a big problem.
>> >> > +	 */
>> >> > +	tmp_tests = tests;
>> >> > +	ret = nftw(".", ftw_attachments_list, 4, FTW_PHYS | FTW_DEPTH);
>> >> 
>> >> I think another option is to use fts(3)? Since it is a streaming API,
>> >> you can keep the state (i.e. the current json object) as a local
>> >> variable and update as you walk the tree.
>> >
>> > CI folks want minimize changes in results.json, so according to above
>> > I would keep everything in flat attachments array.
>> >
>> >> 
>> >> It seems it is not POSIX though.  Not sure if that's a real issue for
>> >> IGT, since stuff in IGT are supposed to run on Linux, right?
>> >
>> > And Android if I'm not wrong.
>> 
>> That's Linux as well, no?  Perhaps just need to have a sanity check to
>> see if those functions are also available there.
>> 
>> >
>> >> 
>> >> Thinking back, I guess it could fts(3) could even be used for the
>> >> recursive removal.
>> >
>> > Question - do we really need this? I can live with ugly static
>> > json at cost of simplicity especially this is only result generator
>> > which likely won't be touched by next months/years...
>> 
>> I would say: if the right tool is available for the job, why not using
>> it?
>> 
>> Not going to block on this though...
>> 
>> >
>> > For attachments case imo allowing recursive creation from hooks scripts
>> > is an overkill.
>> 
>> The hook mechanism is not something created for exclusive use by CI. It
>> is a tool for developers to use are they see fit.  That was my original
>> intention when I first developed the hooks infrastructure.
>> 
>> I don't like the fact that we are making assumptions of how the hooks
>> will behave here.
>> 
>> If CI wants a flat structure, that's fine: let CI provide hooks that
>> generate files in a flat hierarchy.  I just think that it is not right
>> to assume that all hooks will behave like that.
>
> Executing hooks out of igt_runner won't provide results.json, right?
> So all that recursive removal / etc doesn't makes sense when you execute
> tests standalone.

My comment above is not about running igt_runner vs standalone tests;
it is about the users having their own custom hook scripts, which could
be used as part of an igt_runner call.

By the way, did we reach an agreement about whether we should or not be
adding the attachments to the results.json?  I remember Ryszard had his
doubts.  I might have missed some conversation about it.

--
Gustavo Sousa

>
> --
> Zbigniew
>
>
>> 
>> --
>> Gustavo Sousa
>> 
>> >
>> > --
>> > Zbigniew
>> >
>> >> 
>> >> --
>> >> Gustavo Sousa
>> >> 
>> >> > +	fchdir(dirfd(currdir));
>> >> > +
>> >> > +	return ret ? false : true;
>> >> > +}
>> >> > +
>> >> >  static const char *result_from_exitcode(int exitcode)
>> >> >  {
>> >> >  	switch (exitcode) {
>> >> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
>> >> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
>> >> >  	}
>> >> >  
>> >> > +	if (!fill_from_attachments(dirfd, results->tests))
>> >> > +		fprintf(stderr, "Error parsing attachments directory\n");
>> >> > +
>> >> >  	override_results(entry->binary, &subtests, results->tests);
>> >> >  	prune_subtests(settings, entry, &subtests, results->tests);
>> >> >  
>> >> > -- 
>> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks
  2026-04-15 13:48       ` Gustavo Sousa
@ 2026-04-15 16:37         ` Zbigniew Kempczyński
  0 siblings, 0 replies; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15 16:37 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

I hope you don't mind I truncated thread to interesting part of our discussion:

On Wed, Apr 15, 2026 at 10:48:36AM -0300, Gustavo Sousa wrote:

<cut>

> >> 
> >> > +			return -1;
> >> > +		}
> >> > +	} else if (typeflag == FTW_DP) {
> >> > +		if (rmdir(fpath)) {
> >> > +			errf("Cannot remove directory %s\n", fpath);
> >> 
> >> Ditto.
> >> 
> >> > +			return -1;
> >> > +		}
> >> > +	} else {
> >> > +		errf("Cannot remove %s (unsupported file type)\n", fpath);
> >> > +		return -1;
> >> 
> >> I think it would be sensible to drop symbolic links as well (I think it
> >> could be handled in the same brace for FTW_F.
> >
> > I wondered about this, but I would be strict - only files and dirs
> > are allowed in the attachments directory. What for user/script would do
> > symbolic links there?
> 
> Not sure, but I don't see a reason to disallow them.  We can't predict
> what a user hook will do, so I would be in favor of being more flexible
> when we can.

Ok, unlinking symlink is safe so you've conviced me. Especially
it can be simply handled within same switch/case section.

<cut>

> >> > +static bool clear_attachments_dir_recursively(int attdirfd)
> >> > +{
> >> > +	char attdirname[PATH_MAX];
> >> > +	DIR *currdir;
> >> > +	int ret;
> >> > +
> >> > +	currdir = opendir(".");
> >> 
> >> Why do we need this call?
> >
> > nftw() requires path, not fd so I have to ensure I leave working
> > directory intact when I quit the function. I don't know any method
> > apart of fchdir/getcwd() to get dirname I would like to pass to
> > nftw(). And I won't assume I know where's current working dir.
> 
> Ah, I overlooked the fact that currdir is used to get back to the
> directory at the end of the function. My bad.
> 
> That said, I do feel like we are doing a bit too much here and passing
> the path directly would make it simpler (that is, if we were to continue
> to use a separate clear_attachments_dir_recursively() function, as
> opposed to my suggestion below).
> 
> >
> >> 
> >> > +	fchdir(attdirfd);
> >> > +	getcwd(attdirname, sizeof(attdirname));
> >> > +
> >> > +	/* Sanity check we're in attachments directory structure */
> >> > +	if (!strstr(attdirname, DIR_ATTACHMENTS)) {
> >> > +		errf("Cowardly refusing removing in directory which is not "
> >> > +		     "attachments directory [currdir: %s]!\n", attdirname);
> >> > +		ret = -1;
> >> > +		goto out;
> >> > +	}
> >> 
> >> This function is static and only called for DIR_ATTACHMENTS.  I believe
> >> this check is unnecessary.
> >
> > Assuming no bug is here you're right, but I would like to do double check
> > directory content I want to remove is really I expect to.
> 
> I think this check would make sense if things were more complex and
> would make it hard to predict how this function would be called.  I
> don't think that's the case here, though: this is a simple case where
> there is only one call site for this function and it is for the
> DIR_ATTACHMENTS.
> 
> I even think, as mentioned in an earlier reply, that this function could
> be avoided completely, but I won't block on that.

Ok, I'm going to eliminate it. Lets see how it will look like after this
change.

> 
> >
> >> 
> >> > +
> >> > +	ret = nftw(attdirname, ftw_attachment_removal, 4, FTW_PHYS | FTW_DEPTH);
> >> > +
> >> > +out:
> >> > +	fchdir(dirfd(currdir));
> >> > +	closedir(currdir);
> >> > +
> >> > +	return ret ? false : true;
> >> > +}
> >> > +
> >> >  static bool clear_test_result_directory(int dirfd)
> >> 
> >> I think we need to have the path to the test result dir passed as
> >> argument here so that we can build attdirname without having the change
> >> dir + get cwd dance.
> >
> > I didn't want to rewrite clear_old_results() function. Current code
> > uses mostly fd's and only place where I really need path is nftw().
> > I will rewrite to passing paths if you insist but personally I wouldn't
> > do this.
> 
> I think this scenario justifies rewriting clear_old_results() to pass
> the path as well.  We are doing extra steps -- creating attdirfd and
> then, inside clear_attachments_dir_recursively(), all that handling of
> fds -- for no real benefit besides conforming to a "fd as argument"
> standard IMO.

Ok, I walked over the code and probably you're right - providing
path will be simpler then workarounding with fchdir/getcwd.

> 
> >
> >> 
> >> >  {
> >> > -	int i;
> >> > +	int i, attdirfd;
> >> > +	int ret = true;
> >> 
> >> I guess we don't need this ret variable. If the removal of the
> >> attachments directory fails, we can just print an error message and
> >> return false.
> >
> > Ok.
> >
> >> 
> >> >  
> >> >  	for (i = 0; i < _F_LAST; i++) {
> >> >  		if (remove_file(dirfd, filenames[i])) {
> >> > @@ -1960,7 +2019,16 @@ static bool clear_test_result_directory(int dirfd)
> >> >  		}
> >> >  	}
> >> >  
> >> > -	return true;
> >> > +	if ((attdirfd = openat(dirfd, DIR_ATTACHMENTS, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) < 0) {
> >> > +		errf("Cannot open attachments directory\n");
> >> > +		return false;
> >> > +	}
> >> > +
> >> > +	ret = clear_attachments_dir_recursively(attdirfd);
> >> > +	if (!ret)
> >> > +		errf("Cannot clear attachments dir recursively\n");
> >> 
> >> Why not simply call nftw() directly from here? I don't see much value in
> >> having the function clear_attachments_dir_recursively().
> >
> > I created a separate function because I like dividing logical tasks
> > to separate functions. I can unfold this function here if you think
> > this will be better.
> 
> I can live with the separate function.  I just think dropping it greatly
> simplifies the current code.  Your call.

Ok, we'll see how it goes in v4.

--
Zbigniew

> 
> --
> Gustavo Sousa
> 
> >
> > --
> > Zbigniew
> >
> >> 
> >> --
> >> Gustavo Sousa
> >> 
> >> > +
> >> > +	return ret;
> >> >  }
> >> >  
> >> >  static bool clear_old_results(char *path)
> >> > @@ -2002,6 +2070,7 @@ static bool clear_old_results(char *path)
> >> >  			close(dirfd);
> >> >  			return false;
> >> >  		}
> >> > +
> >> >  		close(resdirfd);
> >> >  		if (unlinkat(dirfd, name, AT_REMOVEDIR)) {
> >> >  			errf("Warning: Result directory %s contains extra files\n",
> >> > diff --git a/runner/executor.h b/runner/executor.h
> >> > index 3b1cabcf55..bc6ac80dc4 100644
> >> > --- a/runner/executor.h
> >> > +++ b/runner/executor.h
> >> > @@ -25,6 +25,8 @@ enum {
> >> >  	_F_LAST,
> >> >  };
> >> >  
> >> > +#define DIR_ATTACHMENTS "attachments"
> >> > +
> >> >  bool open_output_files(int dirfd, int *fds, bool write);
> >> >  bool open_output_files_rdonly(int dirfd, int *fds);
> >> >  void close_outputs(int *fds);
> >> > -- 
> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-15 16:20           ` Gustavo Sousa
@ 2026-04-15 19:56             ` Zbigniew Kempczyński
  2026-04-15 20:31               ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-15 19:56 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Wed, Apr 15, 2026 at 01:20:42PM -0300, Gustavo Sousa wrote:

<cut>

> >> 
> >> >
> >> > For attachments case imo allowing recursive creation from hooks scripts
> >> > is an overkill.
> >> 
> >> The hook mechanism is not something created for exclusive use by CI. It
> >> is a tool for developers to use are they see fit.  That was my original
> >> intention when I first developed the hooks infrastructure.
> >> 
> >> I don't like the fact that we are making assumptions of how the hooks
> >> will behave here.
> >> 
> >> If CI wants a flat structure, that's fine: let CI provide hooks that
> >> generate files in a flat hierarchy.  I just think that it is not right
> >> to assume that all hooks will behave like that.
> >
> > Executing hooks out of igt_runner won't provide results.json, right?
> > So all that recursive removal / etc doesn't makes sense when you execute
> > tests standalone.
> 
> My comment above is not about running igt_runner vs standalone tests;
> it is about the users having their own custom hook scripts, which could
> be used as part of an igt_runner call.
> 
> By the way, did we reach an agreement about whether we should or not be
> adding the attachments to the results.json?  I remember Ryszard had his
> doubts.  I might have missed some conversation about it.

Yes. We got some offline discussion about this and Ryszard requirement
was we should pack only attachment filenames to results.json. No content
should land into this file because it is already big and adding content
packed via base64 will only make it bigger.

If you don't mind I would like to provide minimalistic solution which
will provide guc logs first. I suppose you have your own setup which
likely uses hooks much, but at the moment I would like to solve problem
with valid guc logs for failing tests. We may try to satisfy your
workflow in a followup series, but I would like not to loose my primary
goal from the radar.

--
Zbigniew


> 
> --
> Gustavo Sousa
> 
> >
> > --
> > Zbigniew
> >
> >
> >> 
> >> --
> >> Gustavo Sousa
> >> 
> >> >
> >> > --
> >> > Zbigniew
> >> >
> >> >> 
> >> >> --
> >> >> Gustavo Sousa
> >> >> 
> >> >> > +	fchdir(dirfd(currdir));
> >> >> > +
> >> >> > +	return ret ? false : true;
> >> >> > +}
> >> >> > +
> >> >> >  static const char *result_from_exitcode(int exitcode)
> >> >> >  {
> >> >> >  	switch (exitcode) {
> >> >> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
> >> >> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
> >> >> >  	}
> >> >> >  
> >> >> > +	if (!fill_from_attachments(dirfd, results->tests))
> >> >> > +		fprintf(stderr, "Error parsing attachments directory\n");
> >> >> > +
> >> >> >  	override_results(entry->binary, &subtests, results->tests);
> >> >> >  	prune_subtests(settings, entry, &subtests, results->tests);
> >> >> >  
> >> >> > -- 
> >> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json
  2026-04-15 19:56             ` Zbigniew Kempczyński
@ 2026-04-15 20:31               ` Gustavo Sousa
  0 siblings, 0 replies; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-15 20:31 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Wed, Apr 15, 2026 at 01:20:42PM -0300, Gustavo Sousa wrote:
>
> <cut>
>
>> >> 
>> >> >
>> >> > For attachments case imo allowing recursive creation from hooks scripts
>> >> > is an overkill.
>> >> 
>> >> The hook mechanism is not something created for exclusive use by CI. It
>> >> is a tool for developers to use are they see fit.  That was my original
>> >> intention when I first developed the hooks infrastructure.
>> >> 
>> >> I don't like the fact that we are making assumptions of how the hooks
>> >> will behave here.
>> >> 
>> >> If CI wants a flat structure, that's fine: let CI provide hooks that
>> >> generate files in a flat hierarchy.  I just think that it is not right
>> >> to assume that all hooks will behave like that.
>> >
>> > Executing hooks out of igt_runner won't provide results.json, right?
>> > So all that recursive removal / etc doesn't makes sense when you execute
>> > tests standalone.
>> 
>> My comment above is not about running igt_runner vs standalone tests;
>> it is about the users having their own custom hook scripts, which could
>> be used as part of an igt_runner call.
>> 
>> By the way, did we reach an agreement about whether we should or not be
>> adding the attachments to the results.json?  I remember Ryszard had his
>> doubts.  I might have missed some conversation about it.
>
> Yes. We got some offline discussion about this and Ryszard requirement
> was we should pack only attachment filenames to results.json. No content
> should land into this file because it is already big and adding content
> packed via base64 will only make it bigger.

Ah, this makes it simpler then: just an array of paths relative to the
result dir and no need to recreate the hirerarchy in the JSON.  That
would solve my requirement as well.

>
> If you don't mind I would like to provide minimalistic solution which
> will provide guc logs first. I suppose you have your own setup which
> likely uses hooks much, but at the moment I would like to solve problem
> with valid guc logs for failing tests. We may try to satisfy your
> workflow in a followup series, but I would like not to loose my primary
> goal from the radar.

Okay.

>
> --
> Zbigniew
>
>
>> 
>> --
>> Gustavo Sousa
>> 
>> >
>> > --
>> > Zbigniew
>> >
>> >
>> >> 
>> >> --
>> >> Gustavo Sousa
>> >> 
>> >> >
>> >> > --
>> >> > Zbigniew
>> >> >
>> >> >> 
>> >> >> --
>> >> >> Gustavo Sousa
>> >> >> 
>> >> >> > +	fchdir(dirfd(currdir));
>> >> >> > +
>> >> >> > +	return ret ? false : true;
>> >> >> > +}
>> >> >> > +
>> >> >> >  static const char *result_from_exitcode(int exitcode)
>> >> >> >  {
>> >> >> >  	switch (exitcode) {
>> >> >> > @@ -2244,6 +2304,9 @@ static bool parse_test_directory(int dirfd,
>> >> >> >  		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
>> >> >> >  	}
>> >> >> >  
>> >> >> > +	if (!fill_from_attachments(dirfd, results->tests))
>> >> >> > +		fprintf(stderr, "Error parsing attachments directory\n");
>> >> >> > +
>> >> >> >  	override_results(entry->binary, &subtests, results->tests);
>> >> >> >  	prune_subtests(settings, entry, &subtests, results->tests);
>> >> >> >  
>> >> >> > -- 
>> >> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-15 12:51       ` Gustavo Sousa
@ 2026-04-16 18:44         ` Zbigniew Kempczyński
  2026-04-16 19:59           ` Gustavo Sousa
  0 siblings, 1 reply; 34+ messages in thread
From: Zbigniew Kempczyński @ 2026-04-16 18:44 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

On Wed, Apr 15, 2026 at 09:51:19AM -0300, Gustavo Sousa wrote:
> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> 
> > On Tue, Apr 14, 2026 at 05:33:08PM -0300, Gustavo Sousa wrote:
> >> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
> >> 
> >> > We need to explicitly extract guc logs for failed tests so add hook
> >> > script which does it after subtest/dynsubtest execution. As copying to
> >> > attachments takes a lot of time do it only for failing subtests.
> >> >
> >> > Adding this hook script to CI will extend execution time much and
> >> > using allowlist is necessary. Instead of allowlist argument in the
> >> > runner (previous attempt) now script filters such list on its own and
> >> > decides when to move forward and do some post-test actions. Such
> >> > approach is more flexible but moves decision to script what causes
> >> > it is more prone buggy.
> >> >
> >> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> >> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> >> > Cc: Ryszard Knop <ryszard.knop@intel.com>
> >> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
> >> > ---
> >> > v2: install hook to datadir/hooks
> >> > v3: migrate allowlist from runner to script
> >> > ---
> >> >  scripts/hooks/guc_copy.allowlist  |  2 ++
> >> >  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
> >> >  scripts/meson.build               |  3 ++
> >> >  3 files changed, 52 insertions(+)
> >> >  create mode 100644 scripts/hooks/guc_copy.allowlist
> >> >  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
> >> >
> >> > diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
> >> > new file mode 100644
> >> > index 0000000000..04cb3f8298
> >> > --- /dev/null
> >> > +++ b/scripts/hooks/guc_copy.allowlist
> >> 
> >> Do we want really want the allowlist to be part distributed with IGT? I
> >> think we should default it to no allowlist and then CI (or whoever is
> >> using the hook) defines it if that's desired.
> >
> > I think we want this allowlist in igt. If there's a test which requires
> > to copy guc logs due to failure developer who will analyze this can
> > change allowlist without requesting that from CI folks. We already have
> > blocklist management in igt source and moving this allowlist management
> > to CI would split this resposibility. I would keep such management in
> > one place - is igt source code good place for this - I'm not sure, but
> > at the moment it's there.
> 
> Understood.  Yeah, I guess it is fine to keep CI-managed allowlist in
> IGT as well, then.
> 
> Since we have CI blocklists in the tests/intel-ci folder, maybe that's
> where this hook's allowlist should live as well?  Maybe in the future we
> could move intel-ci to belong to the root of the project, since it would
> contain more than testlists.
> 
> Now, I don't think executables generated by IGT apply the blocklists
> automatically, but CI passes the blocklists as argument as part of their
> workflow, right?
> 
> If that's the case, I think it would make sense for the hook to do the
> same.  In other words, my suggestion is that we can have a CI-managed
> allowlist file, but not use it by default -- CI would pass it when using
> the hook.

I already tried this in v1. But Kamil noticed this would apply same
allowlist to all hooks what likely is not we want. For example if we
would have two hook scripts like a.sh and b.sh and a.sh would like
to execute only for igt@test1@basic, and b.sh to execute on
igt@test2@enhanced we would have problem how to distinguish which
line is for which test. It would need to extend allowlist to sth
like:

a.sh:
igt@test1@basic

b.sh:
igt@test2@enhanced

and do more complicated filtering in script than simple grep -q -f.

At the moment I don't see really good solution, each of them have
pros and cons. Current copy_guc_log_on_fail.sh script tries to look
for allowlist first in IGT_HOOK_ALLOWLIST_DIR. CI may not set this
variable, so script will exit due to lack of allowlist (I've migrated
copy_guc_log.allowlist to tests/intel-ci, so it doesn't exist in script
directory anymore and it just quit. So when CI will decide to enable
hooks integration they just need to configure IGT_HOOK_ALLOWLIST_DIR
- they know when tests/intel-ci exists so they can set this env.

Kamil noticed as well instead of using multiple hook scripts we could
use single hook-wrapper.sh, which in turn would contain all hooks
we want to execute. Like:

hook-wrapper.sh:
#!/bin/bash

scripts/hooks/copy_guc_log_on_fail.sh
scripts/hooks/do_another_hook.sh
scripts/hooks/and_another_one.sh
...

Then CI folks would have less work if we would like to enable
another hook. Just single:
--hook 'post-subtest:scripts/hooks/hook-wrapper.sh' \
--hook 'post-dyn-subtest:scripts/hooks/hook-wrapper.sh'

I like his suggestion, we may do more without burdening CI folks
- they just integrate hooks once. Of course we need to be careful
with scripting to not break anything but this applies to enabling
hooks with or without hook-wrapper.sh

What's your opinion about this?

--
Zbigniew

> 
> >
> >> 
> >> > @@ -0,0 +1,2 @@
> >> > +igt@xe_compute@compute-square
> >> > +igt@xe_exec_basic@once-basic@ccs0
> >> > diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
> >> > new file mode 100755
> >> > index 0000000000..595cf5205e
> >> > --- /dev/null
> >> > +++ b/scripts/hooks/guc_copy_on_fail.sh
> >> 
> >> Maybe guc_log_on_fail.sh? I think it is more descriptive than
> >> guc_copy_*, since the latter is a bit vague about what is being copied.
> >
> > I think copy_guc_log_on_fail.sh would describe its intent better.
> 
> Ack.
> 
> >
> >> 
> >> > @@ -0,0 +1,47 @@
> >> > +#!/bin/bash
> >> > +
> >> > +# Hook script for copying guc.log.
> >> > +# Suggested usage with:
> >> > +# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
> >> > +
> >> > +# Copy only for failed subtests as this is time-consuming
> >> > +if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
> >> > +	exit 0
> >> > +fi
> >> > +
> >> > +# Process and copy guc logs only for those specified in allowlist
> >> > +ALLOWLIST="guc_copy.allowlist"
> >> > +scriptdir=$(dirname $(realpath $0))
> >> 
> >> It is safer to use "$0" above.
> >
> > Fix me if I'm wrong but $0 won't contain absolute path if script
> > was executed using relative path like "./scripts/xyz.sh"
> 
> I mean to use "$0" (rather than $0) as argument of realpath.  Actually,
> I think the safest would be:
> 
>   scriptdir=$(dirname "$(realpath "$0")")
> 
> >
> >> 
> >> > +
> >> > +if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
> >> > +	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
> >> > +	exit 0
> >> > +fi
> >> 
> >> Well, we could allow the hook user to define the output and default it
> >> to "$IGT_RUNNER_ATTACHMENTS_DIR/guc_log" if not passed and
> >> $IGT_RUNNER_ATTACHMENTS_DIR is defined.  Otherwise, we should error out
> >> IMO (i.e. exit 1).
> >
> > Ok, in case of missing above enviroment exit with -1 makes sense.
> >
> >> 
> >> As an example, someone could be calling a single test binary directly
> >> and want to use this hook.
> >
> > If standalone test wants to execute hook script which was designed to
> > use within runner it should be executed with proper envs set apriori
> > its execution.
> >
> > I would like to minimize number of envs passed to scripts from the
> > runner - IGT_RUNNER_ATTACHMENTS_DIR should be single mandatory
> > which would point out the script where to write. And single optional
> > mentioned below - IGT_HOOK_ALLOWLIST_DIR in which script could look
> > for allowlist. I didn't set it in the runner because I don't know
> > the allowlist path (this will be know after installing and as DESTDIR=
> > might be used we can't say from the runner perspective where it will
> > be). Assuming script and allowlist will land in same directory (as
> > currently is set in meson) finding it (dirname/realpath) is possible
> > within the script regardless it was installed.
> >
> >> 
> >> We could do some simple argument parsing here or, to make it simpler,
> >> establish that IGT_HOOKS_GUC_LOG_DEST would be such an input variable
> >> (and document it in the doc comment at the start of the script).
> >
> > Multiplying environment is imo bad idea.
> >
> 
> I think the hook should be a standalone tool that could be used for
> either single tests or in the igt_runner environment.  I think we
> should make it easier for both cases, meaning to have a simple way of
> the hook user to define the necesary parameters (destination dir and
> allowlist file) and make it define sensible defaults when it detects
> it is running in a igt_runner environment.
> 
> If you prefer that the hook should be specific for the igt_runner
> environment, then I guess it is fine to avoid the extra work I'm
> suggesting.  We could revisit this in the future if we find users trying
> to use it with standalone tests.
> 
> >> 
> >> > +
> >> > +cd "$IGT_RUNNER_ATTACHMENTS_DIR"
> >> > +
> >> > +# Look for allowlist in following places:
> >> > +# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
> >> > +# 2. Try in <scriptdir>
> >> > +
> >> > +if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
> >> > +	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
> >> > +else
> >> > +	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
> >> > +fi
> >> 
> >> I would just receive the allowlist path from CLI args or, to make it
> >> simpler, from an environment like IGT_HOOKS_GUC_LOG_ALLOWLIST; and I
> >> think we should default to not using any allowlist if none was passed.
> >
> > That's good idea - if script would receive optional arg which is
> > filename it may use it. I'll add this to copy guc log script.
> >
> >> 
> >> > +
> >> > +if [ ! -e "${ALLOWLIST_PATH}" ]; then
> >> > +	exit 0
> >> > +fi
> >> > +
> >> > +STNAME="${IGT_HOOK_TEST_FULLNAME}"
> >> > +echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
> >> > +if [ $? -ne 0 ]; then
> >> > +	exit 0
> >> > +fi
> >> 
> >> This can simplified with:
> >> 
> >>      if ! echo "$IGT_HOOK_TEST_FULLNAME" | grep -q -f "$ALLOWLIST_PATH"; then
> >>         exit 0;
> >>      fi
> >> 
> >> > +
> >> > +for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do
> >> 
> >> Suggestion: use $(cd /sys/kernel/debug/dri && find -name guc_log)...
> >> 
> >> > +	attout=$(echo ${log:23} | sed -e 's/\//_/g')
> >> 
> >> ...and then here we don't need this line...
> >> 
> >> > +	mkdir -p "${STNAME}"
> >> > +	cp "$log" "${STNAME}/${attout}"
> >> 
> >> ...and here we can simply do: cp "$log" "$STNAME/${log////_}".
> >
> > Will apply above in v4.
> >
> >> 
> >> One issue with the find command above is that we could potentially
> >> collect GuC log for other device (not the one under test).  I know that
> >> IGT supports selecting a device via the environment variable
> >> IGT_DEVICE.  I wonder if we should make it set an environment for the
> >> device under test; we could use a different variable name to avoid
> >> issues with the existing one.
> >
> > Good point. Question is - how to pass more than one PCIID in multigpu
> > scenarios? For single card it is simple, we can set IGT_HOOK_LAST_PCIID=
> > for each opened device. I'll take a look to this and share my thoughts.
> 
> Ah, interesting.  I wasn't aware of this possibility; so we do have
> tests that work on multiple devices?
> 
> Yeah, maybe a variable that uses some sort of separator.  I guess this
> needs a separate discussion and we can keep the hook looking for
> guc_log files for any available device for now?  We could add a comment
> noting this behavior.
> 
> --
> Gustavo Sousa
> 
> >
> > Thanks for the review.
> > --
> > Zbigniew
> >
> >> 
> >> --
> >> Gustavo Sousa
> >> 
> >> > +done
> >> > diff --git a/scripts/meson.build b/scripts/meson.build
> >> > index 6e64065c5e..2ce961898d 100644
> >> > --- a/scripts/meson.build
> >> > +++ b/scripts/meson.build
> >> > @@ -15,3 +15,6 @@ endif
> >> >  igt_doc_script = find_program('igt_doc.py', required : build_testplan)
> >> >  gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
> >> >  generate_iga64_codes = find_program('generate_iga64_codes')
> >> > +
> >> > +install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
> >> > +install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
> >> > -- 
> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist
  2026-04-16 18:44         ` Zbigniew Kempczyński
@ 2026-04-16 19:59           ` Gustavo Sousa
  0 siblings, 0 replies; 34+ messages in thread
From: Gustavo Sousa @ 2026-04-16 19:59 UTC (permalink / raw)
  To: Zbigniew Kempczyński
  Cc: igt-dev, Kamil Konieczny, Ryszard Knop, Krzysztof Karas

Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:

> On Wed, Apr 15, 2026 at 09:51:19AM -0300, Gustavo Sousa wrote:
>> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> 
>> > On Tue, Apr 14, 2026 at 05:33:08PM -0300, Gustavo Sousa wrote:
>> >> Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> writes:
>> >> 
>> >> > We need to explicitly extract guc logs for failed tests so add hook
>> >> > script which does it after subtest/dynsubtest execution. As copying to
>> >> > attachments takes a lot of time do it only for failing subtests.
>> >> >
>> >> > Adding this hook script to CI will extend execution time much and
>> >> > using allowlist is necessary. Instead of allowlist argument in the
>> >> > runner (previous attempt) now script filters such list on its own and
>> >> > decides when to move forward and do some post-test actions. Such
>> >> > approach is more flexible but moves decision to script what causes
>> >> > it is more prone buggy.
>> >> >
>> >> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>> >> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>> >> > Cc: Ryszard Knop <ryszard.knop@intel.com>
>> >> > Cc: Krzysztof Karas <krzysztof.karas@intel.com>
>> >> > ---
>> >> > v2: install hook to datadir/hooks
>> >> > v3: migrate allowlist from runner to script
>> >> > ---
>> >> >  scripts/hooks/guc_copy.allowlist  |  2 ++
>> >> >  scripts/hooks/guc_copy_on_fail.sh | 47 +++++++++++++++++++++++++++++++
>> >> >  scripts/meson.build               |  3 ++
>> >> >  3 files changed, 52 insertions(+)
>> >> >  create mode 100644 scripts/hooks/guc_copy.allowlist
>> >> >  create mode 100755 scripts/hooks/guc_copy_on_fail.sh
>> >> >
>> >> > diff --git a/scripts/hooks/guc_copy.allowlist b/scripts/hooks/guc_copy.allowlist
>> >> > new file mode 100644
>> >> > index 0000000000..04cb3f8298
>> >> > --- /dev/null
>> >> > +++ b/scripts/hooks/guc_copy.allowlist
>> >> 
>> >> Do we want really want the allowlist to be part distributed with IGT? I
>> >> think we should default it to no allowlist and then CI (or whoever is
>> >> using the hook) defines it if that's desired.
>> >
>> > I think we want this allowlist in igt. If there's a test which requires
>> > to copy guc logs due to failure developer who will analyze this can
>> > change allowlist without requesting that from CI folks. We already have
>> > blocklist management in igt source and moving this allowlist management
>> > to CI would split this resposibility. I would keep such management in
>> > one place - is igt source code good place for this - I'm not sure, but
>> > at the moment it's there.
>> 
>> Understood.  Yeah, I guess it is fine to keep CI-managed allowlist in
>> IGT as well, then.
>> 
>> Since we have CI blocklists in the tests/intel-ci folder, maybe that's
>> where this hook's allowlist should live as well?  Maybe in the future we
>> could move intel-ci to belong to the root of the project, since it would
>> contain more than testlists.
>> 
>> Now, I don't think executables generated by IGT apply the blocklists
>> automatically, but CI passes the blocklists as argument as part of their
>> workflow, right?
>> 
>> If that's the case, I think it would make sense for the hook to do the
>> same.  In other words, my suggestion is that we can have a CI-managed
>> allowlist file, but not use it by default -- CI would pass it when using
>> the hook.
>
> I already tried this in v1. But Kamil noticed this would apply same
> allowlist to all hooks what likely is not we want. For example if we
> would have two hook scripts like a.sh and b.sh and a.sh would like
> to execute only for igt@test1@basic, and b.sh to execute on
> igt@test2@enhanced we would have problem how to distinguish which
> line is for which test. It would need to extend allowlist to sth
> like:
>
> a.sh:
> igt@test1@basic
>
> b.sh:
> igt@test2@enhanced
>
> and do more complicated filtering in script than simple grep -q -f.

That's not what I meant; I didn't mean a single allowlist to apply
globally.  I meant something along the lines of either:

  igt_runner --hook "post-dyn-subtest:scripts/hooks/copy_guc_log_on_fail.sh --allow-list path/to/allowlist" ...

or

  IGT_HOOKS_GUC_LOG_ALLOWLIST=path/to/allowlist igt_runner --hook "post-dyn-subtest:scripts/hooks/copy_guc_log_on_fail.sh"

>
> At the moment I don't see really good solution, each of them have
> pros and cons. Current copy_guc_log_on_fail.sh script tries to look
> for allowlist first in IGT_HOOK_ALLOWLIST_DIR. CI may not set this
> variable, so script will exit due to lack of allowlist (I've migrated
> copy_guc_log.allowlist to tests/intel-ci, so it doesn't exist in script
> directory anymore and it just quit. So when CI will decide to enable
> hooks integration they just need to configure IGT_HOOK_ALLOWLIST_DIR
> - they know when tests/intel-ci exists so they can set this env.
>
> Kamil noticed as well instead of using multiple hook scripts we could
> use single hook-wrapper.sh, which in turn would contain all hooks
> we want to execute. Like:
>
> hook-wrapper.sh:
> #!/bin/bash
>
> scripts/hooks/copy_guc_log_on_fail.sh
> scripts/hooks/do_another_hook.sh
> scripts/hooks/and_another_one.sh
> ...
>
> Then CI folks would have less work if we would like to enable
> another hook. Just single:
> --hook 'post-subtest:scripts/hooks/hook-wrapper.sh' \
> --hook 'post-dyn-subtest:scripts/hooks/hook-wrapper.sh'
>
> I like his suggestion, we may do more without burdening CI folks
> - they just integrate hooks once. Of course we need to be careful
> with scripting to not break anything but this applies to enabling
> hooks with or without hook-wrapper.sh
>
> What's your opinion about this?

I think a hook wrapper would be fine if that's what is best for CI.  I
just think it should live in some CI-specific folder
(e.g. tests/intel-ci) instead of a general widely available scripts/
dir.  The decision of what hooks to execute is mainly on the user (CI in
this case).

In that case, the path to the allowlist could even be defined in the
hook wrapper, like in the example below.

tests/intel-ci/hook-wrapper.sh:
#!/bin/bash

SCRIPT_DIR=$(dirname "$(realpath "$0")")
IGT_DIR="$SCRIPT_DIR/../.."

guc_log_allowlist="$SCRIPT_DIR/guc_log_allowlist.txt"

$IGT_DIR/scripts/hooks/copy_guc_log_on_fail.sh --allowlist "$guc_log_allowlist"
... # Other hooks

--
Gustavo Sousa
>
> --
> Zbigniew
>
>> 
>> >
>> >> 
>> >> > @@ -0,0 +1,2 @@
>> >> > +igt@xe_compute@compute-square
>> >> > +igt@xe_exec_basic@once-basic@ccs0
>> >> > diff --git a/scripts/hooks/guc_copy_on_fail.sh b/scripts/hooks/guc_copy_on_fail.sh
>> >> > new file mode 100755
>> >> > index 0000000000..595cf5205e
>> >> > --- /dev/null
>> >> > +++ b/scripts/hooks/guc_copy_on_fail.sh
>> >> 
>> >> Maybe guc_log_on_fail.sh? I think it is more descriptive than
>> >> guc_copy_*, since the latter is a bit vague about what is being copied.
>> >
>> > I think copy_guc_log_on_fail.sh would describe its intent better.
>> 
>> Ack.
>> 
>> >
>> >> 
>> >> > @@ -0,0 +1,47 @@
>> >> > +#!/bin/bash
>> >> > +
>> >> > +# Hook script for copying guc.log.
>> >> > +# Suggested usage with:
>> >> > +# --hook 'post-subtest:scripts/hooks/guc_copy_on_fail.sh' --hook 'post-dyn-subtest:scripts/hooks/guc_copy_on_fail.sh'
>> >> > +
>> >> > +# Copy only for failed subtests as this is time-consuming
>> >> > +if [ "${IGT_HOOK_RESULT}" != "FAIL" ]; then
>> >> > +	exit 0
>> >> > +fi
>> >> > +
>> >> > +# Process and copy guc logs only for those specified in allowlist
>> >> > +ALLOWLIST="guc_copy.allowlist"
>> >> > +scriptdir=$(dirname $(realpath $0))
>> >> 
>> >> It is safer to use "$0" above.
>> >
>> > Fix me if I'm wrong but $0 won't contain absolute path if script
>> > was executed using relative path like "./scripts/xyz.sh"
>> 
>> I mean to use "$0" (rather than $0) as argument of realpath.  Actually,
>> I think the safest would be:
>> 
>>   scriptdir=$(dirname "$(realpath "$0")")
>> 
>> >
>> >> 
>> >> > +
>> >> > +if [ -z "$IGT_RUNNER_ATTACHMENTS_DIR" ]; then
>> >> > +	echo "Missing IGT_RUNNER_ATTACHMENTS_DIR env"
>> >> > +	exit 0
>> >> > +fi
>> >> 
>> >> Well, we could allow the hook user to define the output and default it
>> >> to "$IGT_RUNNER_ATTACHMENTS_DIR/guc_log" if not passed and
>> >> $IGT_RUNNER_ATTACHMENTS_DIR is defined.  Otherwise, we should error out
>> >> IMO (i.e. exit 1).
>> >
>> > Ok, in case of missing above enviroment exit with -1 makes sense.
>> >
>> >> 
>> >> As an example, someone could be calling a single test binary directly
>> >> and want to use this hook.
>> >
>> > If standalone test wants to execute hook script which was designed to
>> > use within runner it should be executed with proper envs set apriori
>> > its execution.
>> >
>> > I would like to minimize number of envs passed to scripts from the
>> > runner - IGT_RUNNER_ATTACHMENTS_DIR should be single mandatory
>> > which would point out the script where to write. And single optional
>> > mentioned below - IGT_HOOK_ALLOWLIST_DIR in which script could look
>> > for allowlist. I didn't set it in the runner because I don't know
>> > the allowlist path (this will be know after installing and as DESTDIR=
>> > might be used we can't say from the runner perspective where it will
>> > be). Assuming script and allowlist will land in same directory (as
>> > currently is set in meson) finding it (dirname/realpath) is possible
>> > within the script regardless it was installed.
>> >
>> >> 
>> >> We could do some simple argument parsing here or, to make it simpler,
>> >> establish that IGT_HOOKS_GUC_LOG_DEST would be such an input variable
>> >> (and document it in the doc comment at the start of the script).
>> >
>> > Multiplying environment is imo bad idea.
>> >
>> 
>> I think the hook should be a standalone tool that could be used for
>> either single tests or in the igt_runner environment.  I think we
>> should make it easier for both cases, meaning to have a simple way of
>> the hook user to define the necesary parameters (destination dir and
>> allowlist file) and make it define sensible defaults when it detects
>> it is running in a igt_runner environment.
>> 
>> If you prefer that the hook should be specific for the igt_runner
>> environment, then I guess it is fine to avoid the extra work I'm
>> suggesting.  We could revisit this in the future if we find users trying
>> to use it with standalone tests.
>> 
>> >> 
>> >> > +
>> >> > +cd "$IGT_RUNNER_ATTACHMENTS_DIR"
>> >> > +
>> >> > +# Look for allowlist in following places:
>> >> > +# 1. Try in IGT_HOOK_ALLOWLIST_DIR if this environment exists
>> >> > +# 2. Try in <scriptdir>
>> >> > +
>> >> > +if [ ! -z "$IGT_HOOK_ALLOWLIST_DIR" ]; then
>> >> > +	ALLOWLIST_PATH="${IGT_HOOK_ALLOWLIST_DIR}/${ALLOWLIST}"
>> >> > +else
>> >> > +	ALLOWLIST_PATH="${scriptdir}/${ALLOWLIST}"
>> >> > +fi
>> >> 
>> >> I would just receive the allowlist path from CLI args or, to make it
>> >> simpler, from an environment like IGT_HOOKS_GUC_LOG_ALLOWLIST; and I
>> >> think we should default to not using any allowlist if none was passed.
>> >
>> > That's good idea - if script would receive optional arg which is
>> > filename it may use it. I'll add this to copy guc log script.
>> >
>> >> 
>> >> > +
>> >> > +if [ ! -e "${ALLOWLIST_PATH}" ]; then
>> >> > +	exit 0
>> >> > +fi
>> >> > +
>> >> > +STNAME="${IGT_HOOK_TEST_FULLNAME}"
>> >> > +echo "${STNAME}" | grep -q -f "${ALLOWLIST_PATH}"
>> >> > +if [ $? -ne 0 ]; then
>> >> > +	exit 0
>> >> > +fi
>> >> 
>> >> This can simplified with:
>> >> 
>> >>      if ! echo "$IGT_HOOK_TEST_FULLNAME" | grep -q -f "$ALLOWLIST_PATH"; then
>> >>         exit 0;
>> >>      fi
>> >> 
>> >> > +
>> >> > +for log in $(find /sys/kernel/debug/dri -iname 'guc_log'); do
>> >> 
>> >> Suggestion: use $(cd /sys/kernel/debug/dri && find -name guc_log)...
>> >> 
>> >> > +	attout=$(echo ${log:23} | sed -e 's/\//_/g')
>> >> 
>> >> ...and then here we don't need this line...
>> >> 
>> >> > +	mkdir -p "${STNAME}"
>> >> > +	cp "$log" "${STNAME}/${attout}"
>> >> 
>> >> ...and here we can simply do: cp "$log" "$STNAME/${log////_}".
>> >
>> > Will apply above in v4.
>> >
>> >> 
>> >> One issue with the find command above is that we could potentially
>> >> collect GuC log for other device (not the one under test).  I know that
>> >> IGT supports selecting a device via the environment variable
>> >> IGT_DEVICE.  I wonder if we should make it set an environment for the
>> >> device under test; we could use a different variable name to avoid
>> >> issues with the existing one.
>> >
>> > Good point. Question is - how to pass more than one PCIID in multigpu
>> > scenarios? For single card it is simple, we can set IGT_HOOK_LAST_PCIID=
>> > for each opened device. I'll take a look to this and share my thoughts.
>> 
>> Ah, interesting.  I wasn't aware of this possibility; so we do have
>> tests that work on multiple devices?
>> 
>> Yeah, maybe a variable that uses some sort of separator.  I guess this
>> needs a separate discussion and we can keep the hook looking for
>> guc_log files for any available device for now?  We could add a comment
>> noting this behavior.
>> 
>> --
>> Gustavo Sousa
>> 
>> >
>> > Thanks for the review.
>> > --
>> > Zbigniew
>> >
>> >> 
>> >> --
>> >> Gustavo Sousa
>> >> 
>> >> > +done
>> >> > diff --git a/scripts/meson.build b/scripts/meson.build
>> >> > index 6e64065c5e..2ce961898d 100644
>> >> > --- a/scripts/meson.build
>> >> > +++ b/scripts/meson.build
>> >> > @@ -15,3 +15,6 @@ endif
>> >> >  igt_doc_script = find_program('igt_doc.py', required : build_testplan)
>> >> >  gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
>> >> >  generate_iga64_codes = find_program('generate_iga64_codes')
>> >> > +
>> >> > +install_data('hooks/guc_copy_on_fail.sh', install_dir : datadir / 'hooks')
>> >> > +install_data('hooks/guc_copy.allowlist', install_dir : datadir / 'hooks')
>> >> > -- 
>> >> > 2.43.0

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2026-04-16 19:59 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-13 20:17 [PATCH i-g-t v3 0/5] RFC: Add attachments support Zbigniew Kempczyński
2026-04-13 20:17 ` [PATCH i-g-t v3 1/5] runner: Rename dirfd to avoid clash with dirfd() Zbigniew Kempczyński
2026-04-14  7:40   ` Krzysztof Karas
2026-04-13 20:17 ` [PATCH i-g-t v3 2/5] runner: Create attachments directory to use by hooks Zbigniew Kempczyński
2026-04-14  7:34   ` Krzysztof Karas
2026-04-14 19:13     ` Zbigniew Kempczyński
2026-04-14 19:27   ` Gustavo Sousa
2026-04-15  5:34     ` Zbigniew Kempczyński
2026-04-15 13:48       ` Gustavo Sousa
2026-04-15 16:37         ` Zbigniew Kempczyński
2026-04-13 20:17 ` [PATCH i-g-t v3 3/5] scripts/hooks: Example guc log copy script and allowlist Zbigniew Kempczyński
2026-04-14  8:06   ` Krzysztof Karas
2026-04-14 19:34     ` Zbigniew Kempczyński
2026-04-14 20:33   ` Gustavo Sousa
2026-04-15  8:23     ` Zbigniew Kempczyński
2026-04-15 12:51       ` Gustavo Sousa
2026-04-16 18:44         ` Zbigniew Kempczyński
2026-04-16 19:59           ` Gustavo Sousa
2026-04-13 20:17 ` [PATCH i-g-t v3 4/5] runner/resultgen: Add json array create/get helper Zbigniew Kempczyński
2026-04-14  8:31   ` Krzysztof Karas
2026-04-13 20:17 ` [PATCH i-g-t v3 5/5] runner/resultgen: Insert attachments list into results.json Zbigniew Kempczyński
2026-04-14  9:35   ` Krzysztof Karas
2026-04-14 19:39     ` Zbigniew Kempczyński
2026-04-14 21:39   ` Gustavo Sousa
2026-04-15  6:31     ` Zbigniew Kempczyński
2026-04-15 12:16       ` Gustavo Sousa
2026-04-15 16:09         ` Zbigniew Kempczyński
2026-04-15 16:20           ` Gustavo Sousa
2026-04-15 19:56             ` Zbigniew Kempczyński
2026-04-15 20:31               ` Gustavo Sousa
2026-04-14  1:57 ` ✓ i915.CI.BAT: success for RFC: Add attachments support (rev3) Patchwork
2026-04-14  2:03 ` ✓ Xe.CI.BAT: " Patchwork
2026-04-14  5:30 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-04-14  7:59 ` ✓ i915.CI.Full: success " Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox