Skip to content

Commit 12ffc3b

Browse files
superm1rafaeljw
authored andcommitted
PM: Restrict swap use to later in the suspend sequence
Currently swap is restricted before drivers have had a chance to do their prepare() PM callbacks. Restricting swap this early means that if a driver needs to evict some content from memory into sawp in it's prepare callback, it won't be able to. On AMD dGPUs this can lead to failed suspends under memory pressure situations as all VRAM must be evicted to system memory or swap. Move the swap restriction to right after all devices have had a chance to do the prepare() callback. If there is any problem with the sequence, restore swap in the appropriate dpm resume callbacks or error handling paths. Closes: ROCm/amdgpu#174 Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2362 Signed-off-by: Mario Limonciello <[email protected]> Tested-by: Nat Wittstock <[email protected]> Tested-by: Lucian Langa <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 86731a2 commit 12ffc3b

File tree

6 files changed

+11
-11
lines changed

6 files changed

+11
-11
lines changed

drivers/base/power/main.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,7 @@ void dpm_complete(pm_message_t state)
12361236
*/
12371237
void dpm_resume_end(pm_message_t state)
12381238
{
1239+
pm_restore_gfp_mask();
12391240
dpm_resume(state);
12401241
dpm_complete(state);
12411242
}
@@ -2176,8 +2177,10 @@ int dpm_suspend_start(pm_message_t state)
21762177
error = dpm_prepare(state);
21772178
if (error)
21782179
dpm_save_failed_step(SUSPEND_PREPARE);
2179-
else
2180+
else {
2181+
pm_restrict_gfp_mask();
21802182
error = dpm_suspend(state);
2183+
}
21812184

21822185
dpm_show_time(starttime, state, error, "start");
21832186
return error;

include/linux/suspend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ extern int unregister_pm_notifier(struct notifier_block *nb);
446446
extern void ksys_sync_helper(void);
447447
extern void pm_report_hw_sleep_time(u64 t);
448448
extern void pm_report_max_hw_sleep(u64 t);
449+
void pm_restrict_gfp_mask(void);
450+
void pm_restore_gfp_mask(void);
449451

450452
#define pm_notifier(fn, pri) { \
451453
static struct notifier_block fn##_nb = \
@@ -492,6 +494,9 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
492494
static inline void pm_report_hw_sleep_time(u64 t) {};
493495
static inline void pm_report_max_hw_sleep(u64 t) {};
494496

497+
static inline void pm_restrict_gfp_mask(void) {}
498+
static inline void pm_restore_gfp_mask(void) {}
499+
495500
static inline void ksys_sync_helper(void) {}
496501

497502
#define pm_notifier(fn, pri) do { (void)(fn); } while (0)

kernel/kexec_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,7 @@ int kernel_kexec(void)
11361136
Resume_devices:
11371137
dpm_resume_end(PMSG_RESTORE);
11381138
Resume_console:
1139+
pm_restore_gfp_mask();
11391140
console_resume_all();
11401141
thaw_processes();
11411142
Restore_console:

kernel/power/hibernate.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,6 @@ int hibernation_snapshot(int platform_mode)
423423
}
424424

425425
console_suspend_all();
426-
pm_restrict_gfp_mask();
427426

428427
error = dpm_suspend(PMSG_FREEZE);
429428

@@ -559,7 +558,6 @@ int hibernation_restore(int platform_mode)
559558

560559
pm_prepare_console();
561560
console_suspend_all();
562-
pm_restrict_gfp_mask();
563561
error = dpm_suspend_start(PMSG_QUIESCE);
564562
if (!error) {
565563
error = resume_target_kernel(platform_mode);
@@ -571,7 +569,6 @@ int hibernation_restore(int platform_mode)
571569
BUG_ON(!error);
572570
}
573571
dpm_resume_end(PMSG_RECOVER);
574-
pm_restore_gfp_mask();
575572
console_resume_all();
576573
pm_restore_console();
577574
return error;

kernel/power/power.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,6 @@ static inline void suspend_test_finish(const char *label) {}
239239
/* kernel/power/main.c */
240240
extern int pm_notifier_call_chain_robust(unsigned long val_up, unsigned long val_down);
241241
extern int pm_notifier_call_chain(unsigned long val);
242-
void pm_restrict_gfp_mask(void);
243-
void pm_restore_gfp_mask(void);
244-
#else
245-
static inline void pm_restrict_gfp_mask(void) {}
246-
static inline void pm_restore_gfp_mask(void) {}
247242
#endif
248243

249244
#ifdef CONFIG_HIGHMEM

kernel/power/suspend.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ int suspend_devices_and_enter(suspend_state_t state)
540540
return error;
541541

542542
Recover_platform:
543+
pm_restore_gfp_mask();
543544
platform_recover(state);
544545
goto Resume_devices;
545546
}
@@ -606,9 +607,7 @@ static int enter_state(suspend_state_t state)
606607

607608
trace_suspend_resume(TPS("suspend_enter"), state, false);
608609
pm_pr_dbg("Suspending system (%s)\n", mem_sleep_labels[state]);
609-
pm_restrict_gfp_mask();
610610
error = suspend_devices_and_enter(state);
611-
pm_restore_gfp_mask();
612611

613612
Finish:
614613
events_check_enabled = false;

0 commit comments

Comments
 (0)