Skip to content

Commit 5a8142e

Browse files
superm1antheas
authored andcommitted
PM: Add suspend and hibernate notifications for after freeze
Suspend and hibernate notifications are available specifically when the sequence starts and finishes. However there are no notifications during the process when tasks have been frozen. Introduce two new events `PM_SUSPEND_POST_FREEZE` and `PM_HIBERNATE_POST_FREEZE` that drivers can subscribe to and take different actions specifically knowing userspace is frozen. Suggested-by: Alex Deucher <[email protected]> Signed-off-by: Mario Limonciello <[email protected]>
1 parent 9590c05 commit 5a8142e

File tree

4 files changed

+40
-15
lines changed

4 files changed

+40
-15
lines changed

Documentation/driver-api/pm/notifiers.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ will be called upon the following events by the PM core:
3232
additional work is done between the notifiers and the invocation of PM
3333
callbacks for the "freeze" transition.
3434

35+
``PM_HIBERNATION_POST_FREEZE``
36+
The system is going to hibernate and tasks have just been frozen.
37+
38+
``PM_SUSPEND_PREPARE``
39+
The system is going to suspend, tasks will be frozen immediately. This
40+
is different from ``PM_HIBERNATION_PREPARE`` above, because in this case
41+
additional work is done between the notifiers and the invocation of PM
42+
callbacks for the "freeze" transition.
43+
44+
``PM_SUSPEND_POST_FREEZE``
45+
The system is going to suspend and tasks have just been frozen.
46+
3547
``PM_POST_HIBERNATION``
3648
The system memory state has been restored from a hibernation image or an
3749
error occurred during hibernation. Device restore callbacks have been
@@ -54,9 +66,10 @@ will be called upon the following events by the PM core:
5466
resume callbacks have been executed and tasks have been thawed.
5567

5668
It is generally assumed that whatever the notifiers do for
57-
``PM_HIBERNATION_PREPARE``, should be undone for ``PM_POST_HIBERNATION``.
58-
Analogously, operations carried out for ``PM_SUSPEND_PREPARE`` should be
59-
reversed for ``PM_POST_SUSPEND``.
69+
``PM_HIBERNATION_PREPARE`` and ``PM_HIBERNATION_POST_FREEZE``, should be undone
70+
for ``PM_POST_HIBERNATION``.
71+
Analogously, operations carried out for ``PM_SUSPEND_PREPARE`` and ``PM_SUSPEND_POST_FREEZE``
72+
should be reversed for ``PM_POST_SUSPEND``.
6073

6174
Moreover, if one of the notifiers fails for the ``PM_HIBERNATION_PREPARE`` or
6275
``PM_SUSPEND_PREPARE`` event, the notifiers that have already succeeded for that

include/linux/suspend.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,14 @@ static inline int is_hibernate_resume_dev(dev_t dev) { return 0; }
438438
#endif
439439

440440
/* Hibernation and suspend events */
441-
#define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */
442-
#define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */
443-
#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
444-
#define PM_POST_SUSPEND 0x0004 /* Suspend finished */
445-
#define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */
446-
#define PM_POST_RESTORE 0x0006 /* Restore failed */
441+
#define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */
442+
#define PM_HIBERNATION_POST_FREEZE 0x0002 /* Prepared for hibernation and tasks have been frozen */
443+
#define PM_POST_HIBERNATION 0x0003 /* Hibernation finished */
444+
#define PM_SUSPEND_PREPARE 0x0004 /* Going to suspend the system */
445+
#define PM_SUSPEND_POST_FREEZE 0x0005 /* Prepared and tasks have been frozen */
446+
#define PM_POST_SUSPEND 0x0006 /* Suspend finished */
447+
#define PM_RESTORE_PREPARE 0x0007 /* Going to restore a saved image */
448+
#define PM_POST_RESTORE 0x0008 /* Restore failed */
447449

448450
extern struct mutex system_transition_mutex;
449451

kernel/power/hibernate.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,11 +793,15 @@ int hibernate(void)
793793
if (error)
794794
goto Exit;
795795

796+
error = pm_notifier_call_chain_robust(PM_HIBERNATION_POST_FREEZE, PM_POST_HIBERNATION);
797+
if (error)
798+
goto Thaw;
799+
796800
lock_device_hotplug();
797801
/* Allocate memory management structures */
798802
error = create_basic_memory_bitmaps();
799803
if (error)
800-
goto Thaw;
804+
goto Unlock_hotplug;
801805

802806
error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
803807
if (error || freezer_test_done)
@@ -845,8 +849,9 @@ int hibernate(void)
845849

846850
Free_bitmaps:
847851
free_basic_memory_bitmaps();
848-
Thaw:
852+
Unlock_hotplug:
849853
unlock_device_hotplug();
854+
Thaw:
850855
if (snapshot_test) {
851856
pm_pr_dbg("Checking hibernation image\n");
852857
error = swsusp_check(false);

kernel/power/suspend.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,13 +531,18 @@ static int suspend_prepare(suspend_state_t state)
531531
trace_suspend_resume(TPS("freeze_processes"), 0, true);
532532
error = suspend_freeze_processes();
533533
trace_suspend_resume(TPS("freeze_processes"), 0, false);
534-
if (!error)
535-
return 0;
534+
if (error)
535+
goto Restore;
536+
error = pm_notifier_call_chain_robust(PM_SUSPEND_POST_FREEZE, PM_POST_SUSPEND);
537+
if (error)
538+
goto Thaw;
536539

537-
dpm_save_failed_step(SUSPEND_FREEZE);
538-
pm_notifier_call_chain(PM_POST_SUSPEND);
540+
return 0;
541+
Thaw:
542+
suspend_thaw_processes();
539543
Restore:
540544
pm_restore_console();
545+
dpm_save_failed_step(SUSPEND_FREEZE);
541546
return error;
542547
}
543548

0 commit comments

Comments
 (0)