From bb4fb12ca4b9670551ea775b50fd5db12e3d65a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 2 Apr 2025 15:32:55 +0200 Subject: [PATCH] pm: policy: default: Optimize power state selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update power state selection. Previously, it was iterating over states starting from the last one so the most common short sleep periods were taking the longest time to select. Order is now swapped so that short sleeps will get power state as quick as possible. Signed-off-by: Krzysztof Chruściński --- subsys/pm/policy/policy_default.c | 35 +++++++++++++------------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/subsys/pm/policy/policy_default.c b/subsys/pm/policy/policy_default.c index eaf317d24cf..497cf4219e6 100644 --- a/subsys/pm/policy/policy_default.c +++ b/subsys/pm/policy/policy_default.c @@ -9,13 +9,12 @@ #include #include -extern int32_t max_latency_cyc; - const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) { int64_t cyc = -1; uint8_t num_cpu_states; const struct pm_state_info *cpu_states; + const struct pm_state_info *out_state = NULL; #ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE if (pm_device_is_any_busy()) { @@ -29,29 +28,25 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states); - for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) { + for (uint32_t i = 0; i < num_cpu_states; i++) { const struct pm_state_info *state = &cpu_states[i]; - uint32_t min_residency_cyc, exit_latency_cyc; + uint32_t min_residency_ticks; - /* check if there is a lock on state + substate */ - if (pm_policy_state_lock_is_active(state->state, state->substate_id)) { + min_residency_ticks = + k_us_to_ticks_ceil32(state->min_residency_us + state->exit_latency_us); + + if (ticks < min_residency_ticks) { + /* If current state has higher residency then use the previous state; */ + break; + } + + /* check if state is available. */ + if (!pm_policy_state_is_available(state->state, state->substate_id)) { continue; } - min_residency_cyc = k_us_to_cyc_ceil32(state->min_residency_us); - exit_latency_cyc = k_us_to_cyc_ceil32(state->exit_latency_us); - - /* skip state if it brings too much latency */ - if ((max_latency_cyc >= 0) && - (exit_latency_cyc >= max_latency_cyc)) { - continue; - } - - if ((cyc < 0) || - (cyc >= (min_residency_cyc + exit_latency_cyc))) { - return state; - } + out_state = state; } - return NULL; + return out_state; }