pm: Fix idle post ops on multicore

Post operations have to be tracked per cpu.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2021-11-19 18:23:03 -08:00 committed by Anas Nashif
commit 54176127ec

View file

@ -22,7 +22,7 @@
#include <logging/log.h> #include <logging/log.h>
LOG_MODULE_REGISTER(pm, CONFIG_PM_LOG_LEVEL); LOG_MODULE_REGISTER(pm, CONFIG_PM_LOG_LEVEL);
static bool post_ops_done = true; static ATOMIC_DEFINE(z_post_ops_required, CONFIG_MP_NUM_CPUS);
static sys_slist_t pm_notifiers = SYS_SLIST_STATIC_INIT(&pm_notifiers); static sys_slist_t pm_notifiers = SYS_SLIST_STATIC_INIT(&pm_notifiers);
static struct pm_state_info z_power_states[CONFIG_MP_NUM_CPUS]; static struct pm_state_info z_power_states[CONFIG_MP_NUM_CPUS];
/* bitmask to check if a power state was forced. */ /* bitmask to check if a power state was forced. */
@ -148,6 +148,8 @@ static inline void pm_state_notify(bool entering_state)
void pm_system_resume(void) void pm_system_resume(void)
{ {
uint8_t id = _current_cpu->id;
/* /*
* This notification is called from the ISR of the event * This notification is called from the ISR of the event
* that caused exit from kernel idling after PM operations. * that caused exit from kernel idling after PM operations.
@ -160,10 +162,7 @@ void pm_system_resume(void)
* The kernel scheduler will get control after the ISR finishes * The kernel scheduler will get control after the ISR finishes
* and it may schedule another thread. * and it may schedule another thread.
*/ */
if (!post_ops_done) { if (atomic_test_and_clear_bit(z_post_ops_required, id)) {
uint8_t id = _current_cpu->id;
post_ops_done = true;
exit_pos_ops(z_power_states[id]); exit_pos_ops(z_power_states[id]);
pm_state_notify(false); pm_state_notify(false);
z_power_states[id] = (struct pm_state_info){PM_STATE_ACTIVE, z_power_states[id] = (struct pm_state_info){PM_STATE_ACTIVE,
@ -205,7 +204,6 @@ bool pm_system_suspend(int32_t ticks)
ret = false; ret = false;
goto end; goto end;
} }
post_ops_done = false;
if (ticks != K_TICKS_FOREVER) { if (ticks != K_TICKS_FOREVER) {
/* /*
@ -253,6 +251,7 @@ bool pm_system_suspend(int32_t ticks)
pm_stats_start(); pm_stats_start();
/* Enter power state */ /* Enter power state */
pm_state_notify(true); pm_state_notify(true);
atomic_set_bit(z_post_ops_required, id);
pm_state_set(z_power_states[id]); pm_state_set(z_power_states[id]);
pm_stats_stop(); pm_stats_stop();