Skip to content

Commit ab7e9b0

Browse files
cavokzrafaeljw
authored andcommitted
PM: hibernate: Incorporate concurrency handling
Hibernation concurrency handling is currently delegated to user.c, where it's also used for regulating the access to the snapshot device. In the prospective of making user.c a separate configuration option, such mutual exclusion is brought into hibernate.c and made available through accessor helpers hereby introduced. Signed-off-by: Domenico Andreoli <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 3a4ccdb commit ab7e9b0

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

kernel/power/hibernate.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ bool freezer_test_done;
6767

6868
static const struct platform_hibernation_ops *hibernation_ops;
6969

70+
static atomic_t hibernate_atomic = ATOMIC_INIT(1);
71+
72+
bool hibernate_acquire(void)
73+
{
74+
return atomic_add_unless(&hibernate_atomic, -1, 0);
75+
}
76+
77+
void hibernate_release(void)
78+
{
79+
atomic_inc(&hibernate_atomic);
80+
}
81+
7082
bool hibernation_available(void)
7183
{
7284
return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
@@ -704,7 +716,7 @@ int hibernate(void)
704716

705717
lock_system_sleep();
706718
/* The snapshot device should not be opened while we're running */
707-
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
719+
if (!hibernate_acquire()) {
708720
error = -EBUSY;
709721
goto Unlock;
710722
}
@@ -775,7 +787,7 @@ int hibernate(void)
775787
Exit:
776788
__pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
777789
pm_restore_console();
778-
atomic_inc(&snapshot_device_available);
790+
hibernate_release();
779791
Unlock:
780792
unlock_system_sleep();
781793
pr_info("hibernation exit\n");
@@ -880,7 +892,7 @@ static int software_resume(void)
880892
goto Unlock;
881893

882894
/* The snapshot device should not be opened while we're running */
883-
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
895+
if (!hibernate_acquire()) {
884896
error = -EBUSY;
885897
swsusp_close(FMODE_READ);
886898
goto Unlock;
@@ -911,7 +923,7 @@ static int software_resume(void)
911923
__pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
912924
pm_restore_console();
913925
pr_info("resume failed (%d)\n", error);
914-
atomic_inc(&snapshot_device_available);
926+
hibernate_release();
915927
/* For success case, the suspend path will release the lock */
916928
Unlock:
917929
mutex_unlock(&system_transition_mutex);

kernel/power/power.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ extern int snapshot_write_next(struct snapshot_handle *handle);
154154
extern void snapshot_write_finalize(struct snapshot_handle *handle);
155155
extern int snapshot_image_loaded(struct snapshot_handle *handle);
156156

157-
/* If unset, the snapshot device cannot be open. */
158-
extern atomic_t snapshot_device_available;
157+
extern bool hibernate_acquire(void);
158+
extern void hibernate_release(void);
159159

160160
extern sector_t alloc_swapdev_block(int swap);
161161
extern void free_all_swap_pages(int swap);

kernel/power/user.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ static struct snapshot_data {
3737
bool free_bitmaps;
3838
} snapshot_state;
3939

40-
atomic_t snapshot_device_available = ATOMIC_INIT(1);
41-
4240
static int snapshot_open(struct inode *inode, struct file *filp)
4341
{
4442
struct snapshot_data *data;
@@ -49,13 +47,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
4947

5048
lock_system_sleep();
5149

52-
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
50+
if (!hibernate_acquire()) {
5351
error = -EBUSY;
5452
goto Unlock;
5553
}
5654

5755
if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
58-
atomic_inc(&snapshot_device_available);
56+
hibernate_release();
5957
error = -ENOSYS;
6058
goto Unlock;
6159
}
@@ -92,7 +90,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
9290
__pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
9391
}
9492
if (error)
95-
atomic_inc(&snapshot_device_available);
93+
hibernate_release();
9694

9795
data->frozen = false;
9896
data->ready = false;
@@ -122,7 +120,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
122120
}
123121
pm_notifier_call_chain(data->mode == O_RDONLY ?
124122
PM_POST_HIBERNATION : PM_POST_RESTORE);
125-
atomic_inc(&snapshot_device_available);
123+
hibernate_release();
126124

127125
unlock_system_sleep();
128126

0 commit comments

Comments
 (0)