* [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry
@ 2026-11-02 9:58 Karthik Poosa
2026-11-02 9:58 ` [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend Karthik Poosa
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Karthik Poosa @ 2026-11-02 9:58 UTC (permalink / raw)
To: igt-dev
Cc: rodrigo.vivi, anshuman.gupta, badal.nilawar, raag.jadav,
riana.tauro, sk.anirban, mallesh.koujalagi, soham.purkait,
ravi.kishore.koppuravuri, Karthik Poosa
Existing Xe runtime-PM tests verify root-port D3cold by polling the ACPI
firmware node's real_power_state. This approach cannot verify the state
during system suspend: userspace cannot read sysfs while suspended, and
reading it after resume only reports the post-resume state.
This patch adds ACPI transition-log checking to the system-suspend tests.
It looks for the root port's D0 -> D3cold message in /dev/kmsg across
suspend/resume, deriving the expected ACPI path from the root port's
firmware node and accounting for kmsg escaping.
The relevant ACPI dynamic-debug call site is enabled when needed and
disabled on process exit only if enabled by the test. Validation requires
D3cold support and d3cold_allowed=1. If the root port is already in D3cold
at suspend entry, suspend/resume runs without asserting a new transition.
The check covers basic, execution, VM-bind and MOCS system-suspend tests.
Runtime-PM validation remains unchanged, and explicit D3hot tests retain
their existing behavior.
The log window spans the suspend/resume operation; a runtime D3cold
transition within that window can also satisfy the check. The check
therefore detects a transition within the window rather than uniquely
attributing it to system suspend.
Karthik Poosa (1):
tests/intel/xe_pm: Validate root-port D3cold entry on system suspend
tests/intel/xe_pm.c | 234 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 221 insertions(+), 13 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa @ 2026-11-02 9:58 ` Karthik Poosa 2026-11-11 18:45 ` Rodrigo Vivi 2026-11-02 19:45 ` ✓ Xe.CI.BAT: success for " Patchwork ` (3 subsequent siblings) 4 siblings, 1 reply; 7+ messages in thread From: Karthik Poosa @ 2026-11-02 9:58 UTC (permalink / raw) To: igt-dev Cc: rodrigo.vivi, anshuman.gupta, badal.nilawar, raag.jadav, riana.tauro, sk.anirban, mallesh.koujalagi, soham.purkait, ravi.kishore.koppuravuri, Karthik Poosa When D3cold is supported and allowed, check the root port's ACPI transition log across system suspend and resume for a D0 -> D3cold transition. Skip the transition assertion if the root port is already in D3cold at suspend entry. Signed-off-by: Karthik Poosa <karthik.poosa@intel.com> Assisted-by: LLM --- tests/intel/xe_pm.c | 234 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 221 insertions(+), 13 deletions(-) diff --git a/tests/intel/xe_pm.c b/tests/intel/xe_pm.c index 543f46f5b..2eb70a383 100644 --- a/tests/intel/xe_pm.c +++ b/tests/intel/xe_pm.c @@ -12,8 +12,10 @@ */ #include <dirent.h> +#include <errno.h> #include <limits.h> #include <fcntl.h> +#include <stdio.h> #include <string.h> #include <sys/ioctl.h> @@ -63,6 +65,9 @@ typedef struct { uint64_t orig_threshold; int fw_handle = -1; +static int fd_kmsg = -1; +static char d3cold_kmsg_entry[512]; +static bool acpi_d3cold_debug_enabled_by_test; static pthread_mutex_t suspend_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER; @@ -192,6 +197,120 @@ static void cleanup_d3(device_t device) dpms_on_off(device, DRM_MODE_DPMS_ON); } +static int count_kmsg_entries(int kmsg, const char *entry) +{ + char buf[4096]; + char *kmsg_entry, *p; + const unsigned char *src; + size_t entry_len = strlen(entry); + int count = 0; + ssize_t len; + + igt_assert(entry_len <= (SIZE_MAX - 1) / 4); + kmsg_entry = malloc(4 * entry_len + 1); + igt_assert(kmsg_entry); + + /* Match /dev/kmsg's escaping of backslashes and non-printable bytes. */ + for (src = (const unsigned char *)entry, p = kmsg_entry; *src; src++) { + if (*src < ' ' || *src >= 127 || *src == '\\') + p += sprintf(p, "\\x%02x", (unsigned int)*src); + else + *p++ = *src; + } + *p = '\0'; + + errno = 0; + while ((len = read(kmsg, buf, sizeof(buf) - 1)) > 0) { + buf[len] = '\0'; + if (strstr(buf, kmsg_entry)) { + igt_debug("Found dmesg entry: %s\n", buf); + count++; + } + } + + free(kmsg_entry); + + if (len == 0) + return count; + + igt_assert_f(len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK), + "Unexpected /dev/kmsg read result len=%zd errno=%d\n", len, errno); + + return count; +} + +static void build_rp_d3cold_kmsg_str(struct pci_device *pci_root, char *buf, size_t len) +{ + char path[PATH_MAX], fw_path[256]; + ssize_t n; + int fd; + + snprintf(path, sizeof(path), + "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/firmware_node/path", + pci_root->domain, pci_root->bus, pci_root->dev, pci_root->func); + + fd = open(path, O_RDONLY); + igt_require_fd(fd); + n = read(fd, fw_path, sizeof(fw_path) - 1); + igt_assert_lte(0, (int)n); + fw_path[n] = '\0'; + if (n > 0 && fw_path[n - 1] == '\n') + fw_path[n - 1] = '\0'; + close(fd); + + snprintf(buf, len, "%s: PM: Power state change: D0 -> D3cold", fw_path); +} + +#define ACPI_DYNDDBG_CONTROL "/sys/kernel/debug/dynamic_debug/control" +#define ACPI_D3COLD_DYNDDBG_QUERY \ + "file drivers/acpi/device_pm.c format \"Power state change: %s -> %s\"" + +static bool acpi_d3cold_debug_is_enabled(void) +{ + char line[1024]; + FILE *fp; + bool enabled = false; + + fp = fopen(ACPI_DYNDDBG_CONTROL, "r"); + if (!fp) + return false; + + while (fgets(line, sizeof(line), fp)) { + char *message = strstr(line, "Power state change: %s -> %s"); + char *flags = strchr(line, '='); + + if (message && flags && flags < message && memchr(flags, 'p', message - flags)) { + enabled = true; + break; + } + } + + fclose(fp); + return enabled; +} + +static bool set_acpi_d3cold_debug(bool enable) +{ + FILE *fp; + int ret; + + fp = fopen(ACPI_DYNDDBG_CONTROL, "w"); + if (!fp) + return false; + + ret = fprintf(fp, "%s %sp\n", ACPI_D3COLD_DYNDDBG_QUERY, enable ? "+" : "-"); + if (fclose(fp)) + return false; + + return ret > 0; +} + +static void restore_acpi_d3cold_debug(int sig) +{ + if (acpi_d3cold_debug_enabled_by_test) + set_acpi_d3cold_debug(false); +} + static bool in_d3(device_t device, enum igt_acpi_d_state state) { uint16_t val; @@ -228,6 +347,85 @@ static void close_fw_handle(int sig) close(fw_handle); } +static void close_d3cold_kmsg_handle(int sig) +{ + if (fd_kmsg < 0) + return; + + close(fd_kmsg); + fd_kmsg = -1; +} + +static void start_d3cold_kmsg_logging(void) +{ + igt_require_fd(fd_kmsg); + igt_assert_neq(lseek(fd_kmsg, 0, SEEK_END), -1); +} + +static void check_d3cold_kmsg_count(void) +{ + int count; + + igt_require_fd(fd_kmsg); + count = count_kmsg_entries(fd_kmsg, d3cold_kmsg_entry); + igt_info("Root port D3cold entry count=%d\n", count); + igt_assert_f(count > 0, + "No root port D3cold entry detected during system suspend\n"); +} + +static bool d3cold_validation_enabled(device_t device) +{ + uint32_t d3cold_allowed; + + if (!igt_pm_acpi_d3cold_supported(device.pci_root)) + return false; + + igt_pm_get_d3cold_allowed(device.pci_slot_name, &d3cold_allowed); + + return d3cold_allowed; +} + +static void prepare_d3cold_kmsg(device_t device) +{ + igt_require_f(d3cold_validation_enabled(device), + "D3Cold validation requires a D3Cold-capable root port and d3cold_allowed=1\n"); + + if (fd_kmsg < 0) { + build_rp_d3cold_kmsg_str(device.pci_root, d3cold_kmsg_entry, + sizeof(d3cold_kmsg_entry)); + fd_kmsg = open("/dev/kmsg", O_RDONLY | O_NONBLOCK); + igt_require_fd(fd_kmsg); + } + + if (!acpi_d3cold_debug_is_enabled()) { + igt_require_f(set_acpi_d3cold_debug(true), + "ACPI D3Cold dynamic debug is unavailable\n"); + acpi_d3cold_debug_enabled_by_test = true; + igt_require_f(acpi_d3cold_debug_is_enabled(), + "Failed to enable ACPI D3Cold dynamic debug\n"); + } +} + +static void suspend_check_d3cold(device_t device, enum igt_suspend_state s_state, + enum igt_suspend_test test) +{ + igt_require_f(d3cold_validation_enabled(device), + "D3Cold validation requires a D3Cold-capable root port and d3cold_allowed=1\n"); + + if (igt_pm_get_acpi_real_d_state(device.pci_root) == IGT_ACPI_D3Cold) { + igt_info("Root port already in D3cold at suspend entry; skip transition check\n"); + igt_system_suspend_autoresume(s_state, test); + return; + } + + prepare_d3cold_kmsg(device); + + /* Seek to end before suspend so only new messages are scanned */ + start_d3cold_kmsg_logging(); + igt_system_suspend_autoresume(s_state, test); + check_d3cold_kmsg_count(); +} + #define MAX_VMAS 2 static void* @@ -578,7 +776,7 @@ child_exec(void *arguments) static void test_exec(device_t device, int n_exec_queues, int n_execs, enum igt_suspend_state s_state, enum igt_acpi_d_state d_state, - unsigned int flags) + unsigned int flags, bool validate_d3cold) { enum igt_suspend_test test = s_state == SUSPEND_STATE_DISK ? SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; @@ -587,6 +785,10 @@ test_exec(device_t device, int n_exec_queues, int n_execs, pthread_t threads[65]; /* MAX_ENGINES + 1 */ child_exec_args args; + if (validate_d3cold && n_execs > 1 && s_state != NO_SUSPEND) { + prepare_d3cold_kmsg(device); + } + xe_for_each_engine(device.fd_xe, eci) { args.device = device; args.eci = eci; @@ -607,7 +809,10 @@ test_exec(device_t device, int n_exec_queues, int n_execs, } if (n_execs > 1 && s_state != NO_SUSPEND) { - igt_system_suspend_autoresume(s_state, test); + if (validate_d3cold) + suspend_check_d3cold(device, s_state, test); + else + igt_system_suspend_autoresume(s_state, test); pthread_mutex_lock(&suspend_lock); pthread_cond_broadcast(&suspend_cond); @@ -845,7 +1050,7 @@ static void test_mocs_suspend_resume(device_t device, enum igt_suspend_state s_s enum igt_suspend_test test = s_state == SUSPEND_STATE_DISK ? SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; - igt_system_suspend_autoresume(s_state, test); + suspend_check_d3cold(device, s_state, test); } } igt_assert(igt_debugfs_exists(device.fd_xe, path, O_RDONLY)); @@ -981,7 +1186,7 @@ int igt_main() igt_device_get_pci_slot_name(device.fd_xe, device.pci_slot_name); /* Always perform initial once-basic exec checking for health */ - test_exec(device, 1, 1, NO_SUSPEND, NO_RPM, 0); + test_exec(device, 1, 1, NO_SUSPEND, NO_RPM, 0, false); igt_pm_get_d3cold_allowed(device.pci_slot_name, &d3cold_allowed); has_runtime_pm = igt_setup_runtime_pm(device.fd_xe); @@ -989,6 +1194,8 @@ int igt_main() device.res = drmModeGetResources(device.fd_xe); igt_install_exit_handler(igt_drm_debug_mask_reset_exit_handler); + igt_install_exit_handler(close_d3cold_kmsg_handle); + igt_install_exit_handler(restore_acpi_d3cold_debug); update_debug_mask_if_ci(DRM_UT_KMS); errno = 0; } @@ -997,28 +1204,28 @@ int igt_main() igt_subtest_f("%s-basic", s->name) { enum igt_suspend_test test = s->state == SUSPEND_STATE_DISK ? SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; - igt_system_suspend_autoresume(s->state, test); + suspend_check_d3cold(device, s->state, test); } igt_subtest_f("%s-basic-exec", s->name) { - test_exec(device, 1, 2, s->state, NO_RPM, 0); + test_exec(device, 1, 2, s->state, NO_RPM, 0, true); } igt_subtest_f("%s-exec-after", s->name) { enum igt_suspend_test test = s->state == SUSPEND_STATE_DISK ? SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; - igt_system_suspend_autoresume(s->state, test); - test_exec(device, 1, 2, NO_SUSPEND, NO_RPM, 0); + suspend_check_d3cold(device, s->state, test); + test_exec(device, 1, 2, NO_SUSPEND, NO_RPM, 0, false); } igt_subtest_f("%s-multiple-execs", s->name) { - test_exec(device, 16, 32, s->state, NO_RPM, 0); + test_exec(device, 16, 32, s->state, NO_RPM, 0, true); } for (const struct vm_op *op = vm_op; op->name; op++) { igt_subtest_f("%s-vm-bind-%s", s->name, op->name) { - test_exec(device, 16, 32, s->state, NO_RPM, op->flags); + test_exec(device, 16, 32, s->state, NO_RPM, op->flags, true); } } @@ -1026,7 +1233,8 @@ int igt_main() igt_subtest_f("%s-%s-basic-exec", s->name, d->name) { igt_require_f(has_runtime_pm, "Runtime PM not available\n"); igt_assert(setup_d3(device, d->state)); - test_exec(device, 1, 2, s->state, NO_RPM, 0); + test_exec(device, 1, 2, s->state, NO_RPM, 0, + d->state == IGT_ACPI_D3Cold); cleanup_d3(device); } } @@ -1050,7 +1258,7 @@ int igt_main() igt_subtest_f("%s-basic-exec", d->name) { igt_require_f(has_runtime_pm, "Runtime PM not available\n"); igt_assert(setup_d3(device, d->state)); - test_exec(device, 1, 1, NO_SUSPEND, d->state, 0); + test_exec(device, 1, 1, NO_SUSPEND, d->state, 0, false); cleanup_d3(device); } @@ -1065,7 +1273,7 @@ int igt_main() igt_subtest_f("%s-multiple-execs", d->name) { igt_require_f(has_runtime_pm, "Runtime PM not available\n"); igt_assert(setup_d3(device, d->state)); - test_exec(device, 16, 32, NO_SUSPEND, d->state, 0); + test_exec(device, 16, 32, NO_SUSPEND, d->state, 0, false); cleanup_d3(device); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 ` [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend Karthik Poosa @ 2026-11-11 18:45 ` Rodrigo Vivi 0 siblings, 0 replies; 7+ messages in thread From: Rodrigo Vivi @ 2026-11-11 18:45 UTC (permalink / raw) To: Karthik Poosa Cc: igt-dev, anshuman.gupta, badal.nilawar, raag.jadav, riana.tauro, sk.anirban, mallesh.koujalagi, soham.purkait, ravi.kishore.koppuravuri On Mon, Nov 02, 2026 at 03:28:02PM +0530, Karthik Poosa wrote: > When D3cold is supported and allowed, check the root port's ACPI > transition log across system suspend and resume for a D0 -> D3cold > transition. Skip the transition assertion if the root port is already > in D3cold at suspend entry. > > Signed-off-by: Karthik Poosa <karthik.poosa@intel.com> > Assisted-by: LLM > --- > tests/intel/xe_pm.c | 234 +++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 221 insertions(+), 13 deletions(-) > > diff --git a/tests/intel/xe_pm.c b/tests/intel/xe_pm.c > index 543f46f5b..2eb70a383 100644 > --- a/tests/intel/xe_pm.c > +++ b/tests/intel/xe_pm.c > @@ -12,8 +12,10 @@ > */ > > #include <dirent.h> > +#include <errno.h> > #include <limits.h> > #include <fcntl.h> > +#include <stdio.h> > #include <string.h> > #include <sys/ioctl.h> > > @@ -63,6 +65,9 @@ typedef struct { > > uint64_t orig_threshold; > int fw_handle = -1; > +static int fd_kmsg = -1; > +static char d3cold_kmsg_entry[512]; > +static bool acpi_d3cold_debug_enabled_by_test; > > static pthread_mutex_t suspend_lock = PTHREAD_MUTEX_INITIALIZER; > static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER; > @@ -192,6 +197,120 @@ static void cleanup_d3(device_t device) > dpms_on_off(device, DRM_MODE_DPMS_ON); > } > > +static int count_kmsg_entries(int kmsg, const char *entry) > +{ > + char buf[4096]; > + char *kmsg_entry, *p; > + const unsigned char *src; > + size_t entry_len = strlen(entry); > + int count = 0; > + ssize_t len; > + > + igt_assert(entry_len <= (SIZE_MAX - 1) / 4); > + kmsg_entry = malloc(4 * entry_len + 1); > + igt_assert(kmsg_entry); > + > + /* Match /dev/kmsg's escaping of backslashes and non-printable bytes. */ > + for (src = (const unsigned char *)entry, p = kmsg_entry; *src; src++) { > + if (*src < ' ' || *src >= 127 || *src == '\\') > + p += sprintf(p, "\\x%02x", (unsigned int)*src); > + else > + *p++ = *src; > + } > + *p = '\0'; > + > + errno = 0; > + while ((len = read(kmsg, buf, sizeof(buf) - 1)) > 0) { > + buf[len] = '\0'; > + if (strstr(buf, kmsg_entry)) { > + igt_debug("Found dmesg entry: %s\n", buf); > + count++; > + } > + } > + > + free(kmsg_entry); > + > + if (len == 0) > + return count; > + > + igt_assert_f(len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK), > + "Unexpected /dev/kmsg read result len=%zd errno=%d\n", len, errno); > + > + return count; > +} > + > +static void build_rp_d3cold_kmsg_str(struct pci_device *pci_root, char *buf, size_t len) > +{ > + char path[PATH_MAX], fw_path[256]; > + ssize_t n; > + int fd; > + > + snprintf(path, sizeof(path), > + "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/firmware_node/path", > + pci_root->domain, pci_root->bus, pci_root->dev, pci_root->func); > + > + fd = open(path, O_RDONLY); > + igt_require_fd(fd); > + n = read(fd, fw_path, sizeof(fw_path) - 1); > + igt_assert_lte(0, (int)n); > + fw_path[n] = '\0'; > + if (n > 0 && fw_path[n - 1] == '\n') > + fw_path[n - 1] = '\0'; > + close(fd); > + > + snprintf(buf, len, "%s: PM: Power state change: D0 -> D3cold", fw_path); I'm a bit confused by this message and the order, but I will trust more your tests... > +} > + > +#define ACPI_DYNDDBG_CONTROL "/sys/kernel/debug/dynamic_debug/control" > +#define ACPI_D3COLD_DYNDDBG_QUERY \ > + "file drivers/acpi/device_pm.c format \"Power state change: %s -> %s\"" > + > +static bool acpi_d3cold_debug_is_enabled(void) > +{ > + char line[1024]; > + FILE *fp; > + bool enabled = false; > + > + fp = fopen(ACPI_DYNDDBG_CONTROL, "r"); > + if (!fp) > + return false; > + > + while (fgets(line, sizeof(line), fp)) { > + char *message = strstr(line, "Power state change: %s -> %s"); > + char *flags = strchr(line, '='); > + > + if (message && flags && flags < message && memchr(flags, 'p', message - flags)) { > + enabled = true; > + break; > + } > + } > + > + fclose(fp); > + return enabled; > +} > + > +static bool set_acpi_d3cold_debug(bool enable) > +{ > + FILE *fp; > + int ret; > + > + fp = fopen(ACPI_DYNDDBG_CONTROL, "w"); > + if (!fp) > + return false; > + > + ret = fprintf(fp, "%s %sp\n", ACPI_D3COLD_DYNDDBG_QUERY, enable ? "+" : "-"); > + if (fclose(fp)) > + return false; > + > + return ret > 0; > +} > + > +static void restore_acpi_d3cold_debug(int sig) > +{ > + if (acpi_d3cold_debug_enabled_by_test) > + set_acpi_d3cold_debug(false); > +} > + > static bool in_d3(device_t device, enum igt_acpi_d_state state) > { > uint16_t val; > @@ -228,6 +347,85 @@ static void close_fw_handle(int sig) > close(fw_handle); > } > > +static void close_d3cold_kmsg_handle(int sig) > +{ > + if (fd_kmsg < 0) > + return; > + > + close(fd_kmsg); > + fd_kmsg = -1; > +} > + > +static void start_d3cold_kmsg_logging(void) > +{ > + igt_require_fd(fd_kmsg); > + igt_assert_neq(lseek(fd_kmsg, 0, SEEK_END), -1); > +} > + > +static void check_d3cold_kmsg_count(void) > +{ > + int count; > + > + igt_require_fd(fd_kmsg); > + count = count_kmsg_entries(fd_kmsg, d3cold_kmsg_entry); > + igt_info("Root port D3cold entry count=%d\n", count); > + igt_assert_f(count > 0, > + "No root port D3cold entry detected during system suspend\n"); > +} > + > +static bool d3cold_validation_enabled(device_t device) > +{ > + uint32_t d3cold_allowed; > + > + if (!igt_pm_acpi_d3cold_supported(device.pci_root)) > + return false; > + > + igt_pm_get_d3cold_allowed(device.pci_slot_name, &d3cold_allowed); > + > + return d3cold_allowed; > +} > + > +static void prepare_d3cold_kmsg(device_t device) > +{ > + igt_require_f(d3cold_validation_enabled(device), > + "D3Cold validation requires a D3Cold-capable root port and d3cold_allowed=1\n"); > + > + if (fd_kmsg < 0) { > + build_rp_d3cold_kmsg_str(device.pci_root, d3cold_kmsg_entry, > + sizeof(d3cold_kmsg_entry)); > + fd_kmsg = open("/dev/kmsg", O_RDONLY | O_NONBLOCK); > + igt_require_fd(fd_kmsg); > + } > + > + if (!acpi_d3cold_debug_is_enabled()) { > + igt_require_f(set_acpi_d3cold_debug(true), > + "ACPI D3Cold dynamic debug is unavailable\n"); > + acpi_d3cold_debug_enabled_by_test = true; > + igt_require_f(acpi_d3cold_debug_is_enabled(), > + "Failed to enable ACPI D3Cold dynamic debug\n"); > + } > +} > + > +static void suspend_check_d3cold(device_t device, enum igt_suspend_state s_state, > + enum igt_suspend_test test) > +{ > + igt_require_f(d3cold_validation_enabled(device), > + "D3Cold validation requires a D3Cold-capable root port and d3cold_allowed=1\n"); This makes all the generic suspend subtests skip on machines without d3cold. Please ensure this is only called or checked in d3cold related tests > + > + if (igt_pm_get_acpi_real_d_state(device.pci_root) == IGT_ACPI_D3Cold) { > + igt_info("Root port already in D3cold at suspend entry; skip transition check\n"); > + igt_system_suspend_autoresume(s_state, test); > + return; > + } > + > + prepare_d3cold_kmsg(device); > + > + /* Seek to end before suspend so only new messages are scanned */ > + start_d3cold_kmsg_logging(); > + igt_system_suspend_autoresume(s_state, test); > + check_d3cold_kmsg_count(); > +} > + > #define MAX_VMAS 2 > > static void* > @@ -578,7 +776,7 @@ child_exec(void *arguments) > static void > test_exec(device_t device, int n_exec_queues, int n_execs, > enum igt_suspend_state s_state, enum igt_acpi_d_state d_state, > - unsigned int flags) > + unsigned int flags, bool validate_d3cold) > { > enum igt_suspend_test test = s_state == SUSPEND_STATE_DISK ? > SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; > @@ -587,6 +785,10 @@ test_exec(device_t device, int n_exec_queues, int n_execs, > pthread_t threads[65]; /* MAX_ENGINES + 1 */ > child_exec_args args; > > + if (validate_d3cold && n_execs > 1 && s_state != NO_SUSPEND) { > + prepare_d3cold_kmsg(device); > + } > + > xe_for_each_engine(device.fd_xe, eci) { > args.device = device; > args.eci = eci; > @@ -607,7 +809,10 @@ test_exec(device_t device, int n_exec_queues, int n_execs, > } > > if (n_execs > 1 && s_state != NO_SUSPEND) { > - igt_system_suspend_autoresume(s_state, test); > + if (validate_d3cold) > + suspend_check_d3cold(device, s_state, test); > + else > + igt_system_suspend_autoresume(s_state, test); > > pthread_mutex_lock(&suspend_lock); > pthread_cond_broadcast(&suspend_cond); > @@ -845,7 +1050,7 @@ static void test_mocs_suspend_resume(device_t device, enum igt_suspend_state s_s > enum igt_suspend_test test = s_state == SUSPEND_STATE_DISK ? > SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; > > - igt_system_suspend_autoresume(s_state, test); > + suspend_check_d3cold(device, s_state, test); > } > } > igt_assert(igt_debugfs_exists(device.fd_xe, path, O_RDONLY)); > @@ -981,7 +1186,7 @@ int igt_main() > igt_device_get_pci_slot_name(device.fd_xe, device.pci_slot_name); > > /* Always perform initial once-basic exec checking for health */ > - test_exec(device, 1, 1, NO_SUSPEND, NO_RPM, 0); > + test_exec(device, 1, 1, NO_SUSPEND, NO_RPM, 0, false); > > igt_pm_get_d3cold_allowed(device.pci_slot_name, &d3cold_allowed); > has_runtime_pm = igt_setup_runtime_pm(device.fd_xe); > @@ -989,6 +1194,8 @@ int igt_main() > device.res = drmModeGetResources(device.fd_xe); > > igt_install_exit_handler(igt_drm_debug_mask_reset_exit_handler); > + igt_install_exit_handler(close_d3cold_kmsg_handle); > + igt_install_exit_handler(restore_acpi_d3cold_debug); > update_debug_mask_if_ci(DRM_UT_KMS); > errno = 0; > } > @@ -997,28 +1204,28 @@ int igt_main() > igt_subtest_f("%s-basic", s->name) { > enum igt_suspend_test test = s->state == SUSPEND_STATE_DISK ? > SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; > - igt_system_suspend_autoresume(s->state, test); > + suspend_check_d3cold(device, s->state, test); s4 shouldn't check for d3cold... I believe not even s3... so, let's limit the scope of this test > } > > igt_subtest_f("%s-basic-exec", s->name) { > - test_exec(device, 1, 2, s->state, NO_RPM, 0); > + test_exec(device, 1, 2, s->state, NO_RPM, 0, true); > } > > igt_subtest_f("%s-exec-after", s->name) { > enum igt_suspend_test test = s->state == SUSPEND_STATE_DISK ? > SUSPEND_TEST_DEVICES : SUSPEND_TEST_NONE; > > - igt_system_suspend_autoresume(s->state, test); > - test_exec(device, 1, 2, NO_SUSPEND, NO_RPM, 0); > + suspend_check_d3cold(device, s->state, test); > + test_exec(device, 1, 2, NO_SUSPEND, NO_RPM, 0, false); > } > > igt_subtest_f("%s-multiple-execs", s->name) { > - test_exec(device, 16, 32, s->state, NO_RPM, 0); > + test_exec(device, 16, 32, s->state, NO_RPM, 0, true); > } > > for (const struct vm_op *op = vm_op; op->name; op++) { > igt_subtest_f("%s-vm-bind-%s", s->name, op->name) { > - test_exec(device, 16, 32, s->state, NO_RPM, op->flags); > + test_exec(device, 16, 32, s->state, NO_RPM, op->flags, true); > } > } > > @@ -1026,7 +1233,8 @@ int igt_main() > igt_subtest_f("%s-%s-basic-exec", s->name, d->name) { > igt_require_f(has_runtime_pm, "Runtime PM not available\n"); > igt_assert(setup_d3(device, d->state)); > - test_exec(device, 1, 2, s->state, NO_RPM, 0); > + test_exec(device, 1, 2, s->state, NO_RPM, 0, > + d->state == IGT_ACPI_D3Cold); > cleanup_d3(device); > } > } > @@ -1050,7 +1258,7 @@ int igt_main() > igt_subtest_f("%s-basic-exec", d->name) { > igt_require_f(has_runtime_pm, "Runtime PM not available\n"); > igt_assert(setup_d3(device, d->state)); > - test_exec(device, 1, 1, NO_SUSPEND, d->state, 0); > + test_exec(device, 1, 1, NO_SUSPEND, d->state, 0, false); > cleanup_d3(device); > } > > @@ -1065,7 +1273,7 @@ int igt_main() > igt_subtest_f("%s-multiple-execs", d->name) { > igt_require_f(has_runtime_pm, "Runtime PM not available\n"); > igt_assert(setup_d3(device, d->state)); > - test_exec(device, 16, 32, NO_SUSPEND, d->state, 0); > + test_exec(device, 16, 32, NO_SUSPEND, d->state, 0, false); > cleanup_d3(device); > } > > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* ✓ Xe.CI.BAT: success for tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa 2026-11-02 9:58 ` [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend Karthik Poosa @ 2026-11-02 19:45 ` Patchwork 2026-11-02 19:46 ` ✓ i915.CI.BAT: " Patchwork ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Patchwork @ 2026-11-02 19:45 UTC (permalink / raw) To: Karthik Poosa; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 1086 bytes --] == Series Details == Series: tests/intel/xe_pm: Validate root-port D3cold entry on system suspend URL : https://patchwork.freedesktop.org/series/177433/ State : success == Summary == CI Bug Log - changes from XEIGT_9175_BAT -> XEIGTPW_16084_BAT ==================================================== Summary ------- **SUCCESS** No regressions found. Participating hosts (15 -> 14) ------------------------------ Missing (1): bat-bmg-2 Changes ------- No changes found Build changes ------------- * IGT: IGT_9175 -> IGTPW_16084 * Linux: xe-6046-79cefeb775e63da397152ab01c2f1d4fa1b9b46d -> xe-6047-2cd78713d917a02987f21b437561a5e1e13ddda2 IGTPW_16084: 087594154a27752788c40e9497ffcd68752aee2d @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git IGT_9175: 9175 xe-6046-79cefeb775e63da397152ab01c2f1d4fa1b9b46d: 79cefeb775e63da397152ab01c2f1d4fa1b9b46d xe-6047-2cd78713d917a02987f21b437561a5e1e13ddda2: 2cd78713d917a02987f21b437561a5e1e13ddda2 == Logs == For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_16084/index.html [-- Attachment #2: Type: text/html, Size: 1645 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* ✓ i915.CI.BAT: success for tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa 2026-11-02 9:58 ` [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend Karthik Poosa 2026-11-02 19:45 ` ✓ Xe.CI.BAT: success for " Patchwork @ 2026-11-02 19:46 ` Patchwork 2026-11-02 20:35 ` ✓ Xe.CI.FULL: " Patchwork 2026-11-02 21:31 ` ✓ i915.CI.Full: " Patchwork 4 siblings, 0 replies; 7+ messages in thread From: Patchwork @ 2026-11-02 19:46 UTC (permalink / raw) To: Karthik Poosa; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 1717 bytes --] == Series Details == Series: tests/intel/xe_pm: Validate root-port D3cold entry on system suspend URL : https://patchwork.freedesktop.org/series/177433/ State : success == Summary == CI Bug Log - changes from IGT_9175 -> IGTPW_16084 ==================================================== Summary ------- **SUCCESS** No regressions found. External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/index.html Participating hosts (38 -> 39) ------------------------------ Additional (2): bat-arls-5 bat-adls-6 Missing (1): bat-dg2-13 Known issues ------------ Here are the changes found in IGTPW_16084 that come from known issues: ### IGT changes ### #### Issues hit #### * igt@runner@aborted: - bat-adls-6: NOTRUN -> [FAIL][1] ([i915#17747]) [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/bat-adls-6/igt@runner@aborted.html - bat-arls-5: NOTRUN -> [FAIL][2] ([i915#17747]) [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/bat-arls-5/igt@runner@aborted.html [i915#17747]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/17747 Build changes ------------- * CI: CI-20190529 -> None * IGT: IGT_9175 -> IGTPW_16084 * Linux: CI_DRM_19430 -> CI_DRM_19431 CI-20190529: 20190529 CI_DRM_19430: 79cefeb775e63da397152ab01c2f1d4fa1b9b46d @ git://anongit.freedesktop.org/gfx-ci/linux CI_DRM_19431: 2cd78713d917a02987f21b437561a5e1e13ddda2 @ git://anongit.freedesktop.org/gfx-ci/linux IGTPW_16084: 087594154a27752788c40e9497ffcd68752aee2d @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git IGT_9175: 9175 == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/index.html [-- Attachment #2: Type: text/html, Size: 2403 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* ✓ Xe.CI.FULL: success for tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa ` (2 preceding siblings ...) 2026-11-02 19:46 ` ✓ i915.CI.BAT: " Patchwork @ 2026-11-02 20:35 ` Patchwork 2026-11-02 21:31 ` ✓ i915.CI.Full: " Patchwork 4 siblings, 0 replies; 7+ messages in thread From: Patchwork @ 2026-11-02 20:35 UTC (permalink / raw) To: Karthik Poosa; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 1093 bytes --] == Series Details == Series: tests/intel/xe_pm: Validate root-port D3cold entry on system suspend URL : https://patchwork.freedesktop.org/series/177433/ State : success == Summary == CI Bug Log - changes from XEIGT_9175_FULL -> XEIGTPW_16084_FULL ==================================================== Summary ------- **SUCCESS** No regressions found. Participating hosts (3 -> 3) ------------------------------ No changes in participating hosts Changes ------- No changes found Build changes ------------- * IGT: IGT_9175 -> IGTPW_16084 * Linux: xe-6046-79cefeb775e63da397152ab01c2f1d4fa1b9b46d -> xe-6047-2cd78713d917a02987f21b437561a5e1e13ddda2 IGTPW_16084: 087594154a27752788c40e9497ffcd68752aee2d @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git IGT_9175: 9175 xe-6046-79cefeb775e63da397152ab01c2f1d4fa1b9b46d: 79cefeb775e63da397152ab01c2f1d4fa1b9b46d xe-6047-2cd78713d917a02987f21b437561a5e1e13ddda2: 2cd78713d917a02987f21b437561a5e1e13ddda2 == Logs == For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_16084/index.html [-- Attachment #2: Type: text/html, Size: 1652 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* ✓ i915.CI.Full: success for tests/intel/xe_pm: Validate root-port D3cold entry on system suspend 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa ` (3 preceding siblings ...) 2026-11-02 20:35 ` ✓ Xe.CI.FULL: " Patchwork @ 2026-11-02 21:31 ` Patchwork 4 siblings, 0 replies; 7+ messages in thread From: Patchwork @ 2026-11-02 21:31 UTC (permalink / raw) To: Karthik Poosa; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 6033 bytes --] == Series Details == Series: tests/intel/xe_pm: Validate root-port D3cold entry on system suspend URL : https://patchwork.freedesktop.org/series/177433/ State : success == Summary == CI Bug Log - changes from CI_DRM_19431_full -> IGTPW_16084_full ==================================================== Summary ------- **SUCCESS** No regressions found. External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/index.html Participating hosts (11 -> 10) ------------------------------ Missing (1): pig-kbl-iris Known issues ------------ Here are the changes found in IGTPW_16084_full that come from known issues: ### IGT changes ### #### Possible fixes #### * igt@i915_module_load@load: - shard-tglu: ([PASS][1], [PASS][2], [PASS][3], [PASS][4], [PASS][5], [PASS][6], [PASS][7], [PASS][8], [PASS][9], [PASS][10], [PASS][11], [PASS][12], [PASS][13], [PASS][14], [PASS][15], [PASS][16], [PASS][17], [PASS][18], [SKIP][19], [PASS][20]) ([i915#17257]) -> ([PASS][21], [PASS][22], [PASS][23], [PASS][24], [PASS][25], [PASS][26], [PASS][27], [PASS][28], [PASS][29], [PASS][30], [PASS][31], [PASS][32], [PASS][33], [PASS][34], [PASS][35], [PASS][36], [PASS][37], [PASS][38], [PASS][39]) [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-5/igt@i915_module_load@load.html [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-4/igt@i915_module_load@load.html [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-7/igt@i915_module_load@load.html [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-10/igt@i915_module_load@load.html [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-5/igt@i915_module_load@load.html [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-4/igt@i915_module_load@load.html [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-9/igt@i915_module_load@load.html [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-2/igt@i915_module_load@load.html [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-2/igt@i915_module_load@load.html [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-4/igt@i915_module_load@load.html [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-9/igt@i915_module_load@load.html [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-10/igt@i915_module_load@load.html [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-8/igt@i915_module_load@load.html [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-3/igt@i915_module_load@load.html [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-2/igt@i915_module_load@load.html [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-9/igt@i915_module_load@load.html [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-8/igt@i915_module_load@load.html [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-5/igt@i915_module_load@load.html [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-7/igt@i915_module_load@load.html [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19431/shard-tglu-3/igt@i915_module_load@load.html [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-10/igt@i915_module_load@load.html [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-10/igt@i915_module_load@load.html [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-2/igt@i915_module_load@load.html [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-2/igt@i915_module_load@load.html [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-3/igt@i915_module_load@load.html [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-3/igt@i915_module_load@load.html [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-4/igt@i915_module_load@load.html [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-4/igt@i915_module_load@load.html [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-5/igt@i915_module_load@load.html [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-5/igt@i915_module_load@load.html [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-5/igt@i915_module_load@load.html [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-7/igt@i915_module_load@load.html [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-7/igt@i915_module_load@load.html [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-8/igt@i915_module_load@load.html [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-8/igt@i915_module_load@load.html [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-8/igt@i915_module_load@load.html [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-9/igt@i915_module_load@load.html [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-9/igt@i915_module_load@load.html [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/shard-tglu-9/igt@i915_module_load@load.html [i915#17257]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/17257 Build changes ------------- * CI: CI-20190529 -> None * IGT: IGT_9175 -> IGTPW_16084 * Piglit: piglit_4509 -> None CI-20190529: 20190529 CI_DRM_19431: 2cd78713d917a02987f21b437561a5e1e13ddda2 @ git://anongit.freedesktop.org/gfx-ci/linux IGTPW_16084: 087594154a27752788c40e9497ffcd68752aee2d @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git IGT_9175: 9175 piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_16084/index.html [-- Attachment #2: Type: text/html, Size: 6665 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-11 18:48 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-02 9:58 [PATCH i-g-t 0/1] tests/intel/xe_pm: Check root-port D3cold entry Karthik Poosa 2026-11-02 9:58 ` [PATCH i-g-t] tests/intel/xe_pm: Validate root-port D3cold entry on system suspend Karthik Poosa 2026-11-11 18:45 ` Rodrigo Vivi 2026-11-02 19:45 ` ✓ Xe.CI.BAT: success for " Patchwork 2026-11-02 19:46 ` ✓ i915.CI.BAT: " Patchwork 2026-11-02 20:35 ` ✓ Xe.CI.FULL: " Patchwork 2026-11-02 21:31 ` ✓ i915.CI.Full: " Patchwork
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox