Skip to content

Commit a5dbbb3

Browse files
committed
Merge tag 'pm-6.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix three regressions, two recent ones and one introduced during the 6.17 development cycle: - Add an exit latency check to the menu cpuidle governor in the case when it considers using a real idle state instead of a polling one to address a performance regression (Rafael Wysocki) - Revert an attempted cleanup of a system suspend code path that introduced a regression elsewhere (Samuel Wu) - Allow pm_restrict_gfp_mask() to be called multiple times in a row and adjust pm_restore_gfp_mask() accordingly to avoid having to play nasty games with these calls during hibernation (Rafael Wysocki)" * tag 'pm-6.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM: sleep: Allow pm_restrict_gfp_mask() stacking cpuidle: governors: menu: Select polling state in some more cases Revert "PM: sleep: Make pm_wakeup_clear() call more clear"
2 parents a4819ac + 590c5cd commit a5dbbb3

File tree

5 files changed

+23
-12
lines changed

5 files changed

+23
-12
lines changed

drivers/cpuidle/governors/menu.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
318318

319319
/*
320320
* Use a physical idle state, not busy polling, unless a timer
321-
* is going to trigger soon enough.
321+
* is going to trigger soon enough or the exit latency of the
322+
* idle state in question is greater than the predicted idle
323+
* duration.
322324
*/
323325
if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) &&
324-
s->target_residency_ns <= data->next_timer_ns) {
326+
s->target_residency_ns <= data->next_timer_ns &&
327+
s->exit_latency_ns <= predicted_ns) {
325328
predicted_ns = s->target_residency_ns;
326329
idx = i;
327330
break;

kernel/power/hibernate.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,6 @@ static void power_down(void)
706706

707707
#ifdef CONFIG_SUSPEND
708708
if (hibernation_mode == HIBERNATION_SUSPEND) {
709-
pm_restore_gfp_mask();
710709
error = suspend_devices_and_enter(mem_sleep_current);
711710
if (!error)
712711
goto exit;
@@ -746,9 +745,6 @@ static void power_down(void)
746745
cpu_relax();
747746

748747
exit:
749-
/* Match the pm_restore_gfp_mask() call in hibernate(). */
750-
pm_restrict_gfp_mask();
751-
752748
/* Restore swap signature. */
753749
error = swsusp_unmark();
754750
if (error)

kernel/power/main.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,35 @@
3131
* held, unless the suspend/hibernate code is guaranteed not to run in parallel
3232
* with that modification).
3333
*/
34+
static unsigned int saved_gfp_count;
3435
static gfp_t saved_gfp_mask;
3536

3637
void pm_restore_gfp_mask(void)
3738
{
3839
WARN_ON(!mutex_is_locked(&system_transition_mutex));
39-
if (saved_gfp_mask) {
40-
gfp_allowed_mask = saved_gfp_mask;
41-
saved_gfp_mask = 0;
42-
}
40+
41+
if (WARN_ON(!saved_gfp_count) || --saved_gfp_count)
42+
return;
43+
44+
gfp_allowed_mask = saved_gfp_mask;
45+
saved_gfp_mask = 0;
46+
47+
pm_pr_dbg("GFP mask restored\n");
4348
}
4449

4550
void pm_restrict_gfp_mask(void)
4651
{
4752
WARN_ON(!mutex_is_locked(&system_transition_mutex));
48-
WARN_ON(saved_gfp_mask);
53+
54+
if (saved_gfp_count++) {
55+
WARN_ON((saved_gfp_mask & ~(__GFP_IO | __GFP_FS)) != gfp_allowed_mask);
56+
return;
57+
}
58+
4959
saved_gfp_mask = gfp_allowed_mask;
5060
gfp_allowed_mask &= ~(__GFP_IO | __GFP_FS);
61+
62+
pm_pr_dbg("GFP mask restricted\n");
5163
}
5264

5365
unsigned int lock_system_sleep(void)

kernel/power/process.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ int freeze_processes(void)
132132
if (!pm_freezing)
133133
static_branch_inc(&freezer_active);
134134

135+
pm_wakeup_clear(0);
135136
pm_freezing = true;
136137
error = try_to_freeze_tasks(true);
137138
if (!error)

kernel/power/suspend.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ static int enter_state(suspend_state_t state)
595595
}
596596

597597
pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
598-
pm_wakeup_clear(0);
599598
pm_suspend_clear_flags();
600599
error = suspend_prepare(state);
601600
if (error)

0 commit comments

Comments
 (0)