diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2022-07-13 11:07:27 -0400 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2022-08-03 12:01:07 -0400 |
commit | 9cee84921554ec24df0933cce42e433f5aab097c (patch) | |
tree | b96c53d2add49666c5e25cabfbb56e6c756994a1 | |
parent | fba96418acea17a3ceeb769926284fb3e0e30d64 (diff) |
lib/igt_aux: Introduce the ability to force S3 suspend state.
Testing both Suspend-to-Idle and Suspend-to-RAM is critical.
So far our test suite are relying on the system's default
for the "suspend-to-mem", what reduces our ability to cover
multiple scenarios or requires manual intervention.
This also brings confusions in some debugging scenarios.
For the Suspend-to-Idle it is easy. The FREEZE state already
enforces it. However, there's only one way to enforce the
Suspend-to-RAM (aka S3) which is using MEM state with mem_sleep
at "deep".
However, let's not break the whole world overnight. Let's
first introduce the ability to force the Suspend-to-RAM.
Then convert the tests as needed.
So, the SUSPEND_STATE_MEM will continue to exist and do
exactly what is expected when you set "mem" to /sys/power/state,
which is respect whatever is in the /sys/power/mem_sleep.
Let's introduce a new SUSPEND_STATE_S3 state aiming to force
the Suspend-to-RAM, by changing both /sys/power/state and
/sys/power/mem_sleep.
Cc: Riana Tauro <riana.tauro@intel.com>
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
-rw-r--r-- | lib/igt_aux.c | 118 | ||||
-rw-r--r-- | lib/igt_aux.h | 19 |
2 files changed, 84 insertions, 53 deletions
diff --git a/lib/igt_aux.c b/lib/igt_aux.c index 805550d12..286f4a922 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -698,7 +698,8 @@ static int autoresume_delay; static const char *suspend_state_name[] = { [SUSPEND_STATE_FREEZE] = "freeze", [SUSPEND_STATE_STANDBY] = "standby", - [SUSPEND_STATE_MEM] = "mem", + [SUSPEND_STATE_S3] = "mem", /* Forces Suspend-to-Ram (S3) */ + [SUSPEND_STATE_MEM] = "mem", /* Respects system default */ [SUSPEND_STATE_DISK] = "disk", }; @@ -833,6 +834,63 @@ static bool is_state_supported(int power_dir, enum igt_suspend_state state) } /** + * igt_get_memsleep_state + * + * Reads the value of /sys/power/mem_sleep and + * returns the current suspend state associated with 'mem'. + * + * Returns : an #igt_mem_sleep state, current suspend state associated with 'mem'. + */ +int igt_get_memsleep_state(void) +{ + char *mem_sleep_states; + char *mem_sleep_state; + enum igt_mem_sleep mem_sleep; + int power_dir; + + igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0); + + if (faccessat(power_dir, "mem_sleep", R_OK, 0)) + return MEM_SLEEP_NONE; + + igt_assert((mem_sleep_states = igt_sysfs_get(power_dir, "mem_sleep"))); + for (mem_sleep_state = strtok(mem_sleep_states, " "); mem_sleep_state; + mem_sleep_state = strtok(NULL, " ")) { + if (mem_sleep_state[0] == '[') { + mem_sleep_state[strlen(mem_sleep_state) - 1] = '\0'; + mem_sleep_state++; + break; + } + } + + if (!mem_sleep_state) { + free(mem_sleep_states); + return MEM_SLEEP_NONE; + } + + for (mem_sleep = MEM_SLEEP_S2IDLE; mem_sleep < MEM_SLEEP_NUM; mem_sleep++) { + if (strcmp(mem_sleep_name[mem_sleep], mem_sleep_state) == 0) + break; + } + + igt_assert_f(mem_sleep < MEM_SLEEP_NUM, "Invalid mem_sleep state\n"); + + free(mem_sleep_states); + close(power_dir); + return mem_sleep; +} + +static void set_mem_sleep(int power_dir, enum igt_mem_sleep sleep) +{ + igt_assert(sleep < MEM_SLEEP_NUM); + + igt_assert_eq(faccessat(power_dir, "mem_sleep", W_OK, 0), 0); + + igt_assert(igt_sysfs_set(power_dir, "mem_sleep", + mem_sleep_name[sleep])); +} + +/** * igt_system_suspend_autoresume: * @state: an #igt_suspend_state, the target suspend state * @test: an #igt_suspend_test, test point at which to complete the suspend @@ -858,6 +916,7 @@ void igt_system_suspend_autoresume(enum igt_suspend_state state, { int power_dir; enum igt_suspend_test orig_test; + enum igt_mem_sleep orig_mem_sleep = MEM_SLEEP_NONE; igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0); igt_require(is_state_supported(power_dir, state)); @@ -869,6 +928,14 @@ void igt_system_suspend_autoresume(enum igt_suspend_state state, "Suspend to disk requires swap space.\n"); orig_test = get_suspend_test(power_dir); + + if (state == SUSPEND_STATE_S3) { + orig_mem_sleep = igt_get_memsleep_state(); + set_mem_sleep(power_dir, MEM_SLEEP_DEEP); + igt_skip_on_f(igt_get_memsleep_state() != MEM_SLEEP_DEEP, + "S3 not possible in this system.\n"); + } + set_suspend_test(power_dir, test); if (test == SUSPEND_TEST_NONE) @@ -876,6 +943,9 @@ void igt_system_suspend_autoresume(enum igt_suspend_state state, else suspend_via_sysfs(power_dir, state); + if (orig_mem_sleep) + set_mem_sleep(power_dir, orig_mem_sleep); + set_suspend_test(power_dir, orig_test); close(power_dir); } @@ -951,52 +1021,6 @@ int igt_get_autoresume_delay(enum igt_suspend_state state) } /** - * igt_get_memsleep_state - * - * Reads the value of /sys/power/mem_sleep and - * returns the current suspend state associated with 'mem'. - * - * Returns : an #igt_mem_sleep state, current suspend state associated with 'mem'. - */ -int igt_get_memsleep_state(void) -{ - char *mem_sleep_states; - char *mem_sleep_state; - enum igt_mem_sleep mem_sleep; - int power_dir; - - igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0); - - if (faccessat(power_dir, "mem_sleep", R_OK, 0)) - return MEM_SLEEP_NONE; - - igt_assert((mem_sleep_states = igt_sysfs_get(power_dir, "mem_sleep"))); - for (mem_sleep_state = strtok(mem_sleep_states, " "); mem_sleep_state; - mem_sleep_state = strtok(NULL, " ")) { - if (mem_sleep_state[0] == '[') { - mem_sleep_state[strlen(mem_sleep_state) - 1] = '\0'; - mem_sleep_state++; - break; - } - } - - if (!mem_sleep_state) { - free(mem_sleep_states); - return MEM_SLEEP_NONE; - } - - for (mem_sleep = MEM_SLEEP_S2IDLE; mem_sleep < MEM_SLEEP_NUM; mem_sleep++) { - if (strcmp(mem_sleep_name[mem_sleep], mem_sleep_state) == 0) - break; - } - - igt_assert_f(mem_sleep < MEM_SLEEP_NUM, "Invalid mem_sleep state\n"); - - free(mem_sleep_states); - close(power_dir); - return mem_sleep; -} -/** * igt_drop_root: * * Drop root privileges and make sure it actually worked. Useful for tests diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 9d5b7bd2f..b1e48b0f8 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -135,13 +135,19 @@ bool igt_aub_dump_enabled(void); /** * igt_suspend_state: - * @SUSPEND_STATE_FREEZE: suspend-to-idle target state, aka S0ix or freeze, + * @SUSPEND_STATE_FREEZE: Suspend-To-Idle target state, aka S0ix or freeze, * first non-hibernation state - * @SUSPEND_STATE_STANDBY: standby target state, aka S1, second + * @SUSPEND_STATE_STANDBY: "Power-On Suspend" target state, aka S1, second * non-hibernation state - * @SUSPEND_STATE_MEM: suspend-to-mem target state aka S3, third - * non-hibernation state - * @SUSPEND_STATE_DISK: suspend-to-disk target state, aka S4 or hibernation + * @SUSPEND_STATE_S3: Suspend-To-RAM: It enforces a "deep" state to mem_sleep, + * what forces the system to go to the third + * non-hibernation state, aka S3. + * @SUSPEND_STATE_MEM: A memory sleep (non-hibernation) target state, + * respecting the system's mem_sleep default: + * s2idle: Suspend-To-Idle target state + * shallow: "Power-On Suspend" + * deep: Suspend-To-RAM + * @SUSPEND_STATE_DISK: Suspend-To-Disk target state, aka S4 or hibernation * * Target suspend states used with igt_system_suspend_autoresume(). * See /sys/power/state for the available states on a given machine. @@ -149,7 +155,8 @@ bool igt_aub_dump_enabled(void); enum igt_suspend_state { SUSPEND_STATE_FREEZE, SUSPEND_STATE_STANDBY, - SUSPEND_STATE_MEM, + SUSPEND_STATE_S3, /* Forces Suspend-to-Ram (S3) */ + SUSPEND_STATE_MEM, /* Respects system default */ SUSPEND_STATE_DISK, /*< private >*/ |