Skip to content

Commit

Permalink
PM: suspend: Do not pause cpuidle in the suspend-to-idle path
Browse files Browse the repository at this point in the history
It is pointless to pause cpuidle in the suspend-to-idle path,
because it is going to be resumed in the same path later and
pausing it does not serve any particular purpose in that case.

Rework the code to avoid doing that.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Rafael J. Wysocki committed Oct 26, 2021
1 parent 928265e commit 8d89835
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
11 changes: 6 additions & 5 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,6 @@ void dpm_resume_noirq(pm_message_t state)

resume_device_irqs();
device_wakeup_disarm_wake_irqs();

cpuidle_resume();
}

/**
Expand Down Expand Up @@ -881,6 +879,7 @@ void dpm_resume_early(pm_message_t state)
void dpm_resume_start(pm_message_t state)
{
dpm_resume_noirq(state);
cpuidle_resume();
dpm_resume_early(state);
}
EXPORT_SYMBOL_GPL(dpm_resume_start);
Expand Down Expand Up @@ -1337,8 +1336,6 @@ int dpm_suspend_noirq(pm_message_t state)
{
int ret;

cpuidle_pause();

device_wakeup_arm_wake_irqs();
suspend_device_irqs();

Expand Down Expand Up @@ -1522,9 +1519,13 @@ int dpm_suspend_end(pm_message_t state)
if (error)
goto out;

cpuidle_pause();

error = dpm_suspend_noirq(state);
if (error)
if (error) {
cpuidle_resume();
dpm_resume_early(resume_event(state));
}

out:
dpm_show_time(starttime, state, error, "end");
Expand Down
8 changes: 6 additions & 2 deletions kernel/power/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,13 @@ static void s2idle_enter(void)
raw_spin_unlock_irq(&s2idle_lock);

cpus_read_lock();
cpuidle_resume();

/* Push all the CPUs into the idle loop. */
wake_up_all_idle_cpus();
/* Make the current CPU wait so it can enter the idle loop too. */
swait_event_exclusive(s2idle_wait_head,
s2idle_state == S2IDLE_STATE_WAKE);

cpuidle_pause();
cpus_read_unlock();

raw_spin_lock_irq(&s2idle_lock);
Expand Down Expand Up @@ -405,6 +403,9 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
if (error)
goto Devices_early_resume;

if (state != PM_SUSPEND_TO_IDLE)
cpuidle_pause();

error = dpm_suspend_noirq(PMSG_SUSPEND);
if (error) {
pr_err("noirq suspend of devices failed\n");
Expand Down Expand Up @@ -459,6 +460,9 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
dpm_resume_noirq(PMSG_RESUME);

Platform_early_resume:
if (state != PM_SUSPEND_TO_IDLE)
cpuidle_resume();

platform_resume_early(state);

Devices_early_resume:
Expand Down

0 comments on commit 8d89835

Please sign in to comment.