diff options
Diffstat (limited to 'kernel/power/user.c')
-rw-r--r-- | kernel/power/user.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c index 4ed81e74f86f..957f06164ad1 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -39,6 +39,7 @@ static struct snapshot_data { | |||
39 | char frozen; | 39 | char frozen; |
40 | char ready; | 40 | char ready; |
41 | char platform_support; | 41 | char platform_support; |
42 | bool free_bitmaps; | ||
42 | } snapshot_state; | 43 | } snapshot_state; |
43 | 44 | ||
44 | atomic_t snapshot_device_available = ATOMIC_INIT(1); | 45 | atomic_t snapshot_device_available = ATOMIC_INIT(1); |
@@ -60,11 +61,6 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
60 | error = -ENOSYS; | 61 | error = -ENOSYS; |
61 | goto Unlock; | 62 | goto Unlock; |
62 | } | 63 | } |
63 | if(create_basic_memory_bitmaps()) { | ||
64 | atomic_inc(&snapshot_device_available); | ||
65 | error = -ENOMEM; | ||
66 | goto Unlock; | ||
67 | } | ||
68 | nonseekable_open(inode, filp); | 64 | nonseekable_open(inode, filp); |
69 | data = &snapshot_state; | 65 | data = &snapshot_state; |
70 | filp->private_data = data; | 66 | filp->private_data = data; |
@@ -87,13 +83,16 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
87 | data->swap = -1; | 83 | data->swap = -1; |
88 | data->mode = O_WRONLY; | 84 | data->mode = O_WRONLY; |
89 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | 85 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
86 | if (!error) { | ||
87 | error = create_basic_memory_bitmaps(); | ||
88 | data->free_bitmaps = !error; | ||
89 | } | ||
90 | if (error) | 90 | if (error) |
91 | pm_notifier_call_chain(PM_POST_RESTORE); | 91 | pm_notifier_call_chain(PM_POST_RESTORE); |
92 | } | 92 | } |
93 | if (error) { | 93 | if (error) |
94 | free_basic_memory_bitmaps(); | ||
95 | atomic_inc(&snapshot_device_available); | 94 | atomic_inc(&snapshot_device_available); |
96 | } | 95 | |
97 | data->frozen = 0; | 96 | data->frozen = 0; |
98 | data->ready = 0; | 97 | data->ready = 0; |
99 | data->platform_support = 0; | 98 | data->platform_support = 0; |
@@ -111,12 +110,14 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
111 | lock_system_sleep(); | 110 | lock_system_sleep(); |
112 | 111 | ||
113 | swsusp_free(); | 112 | swsusp_free(); |
114 | free_basic_memory_bitmaps(); | ||
115 | data = filp->private_data; | 113 | data = filp->private_data; |
116 | free_all_swap_pages(data->swap); | 114 | free_all_swap_pages(data->swap); |
117 | if (data->frozen) { | 115 | if (data->frozen) { |
118 | pm_restore_gfp_mask(); | 116 | pm_restore_gfp_mask(); |
117 | free_basic_memory_bitmaps(); | ||
119 | thaw_processes(); | 118 | thaw_processes(); |
119 | } else if (data->free_bitmaps) { | ||
120 | free_basic_memory_bitmaps(); | ||
120 | } | 121 | } |
121 | pm_notifier_call_chain(data->mode == O_RDONLY ? | 122 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
122 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 123 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
@@ -207,6 +208,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
207 | if (!mutex_trylock(&pm_mutex)) | 208 | if (!mutex_trylock(&pm_mutex)) |
208 | return -EBUSY; | 209 | return -EBUSY; |
209 | 210 | ||
211 | lock_device_hotplug(); | ||
210 | data = filp->private_data; | 212 | data = filp->private_data; |
211 | 213 | ||
212 | switch (cmd) { | 214 | switch (cmd) { |
@@ -220,14 +222,23 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
220 | printk("done.\n"); | 222 | printk("done.\n"); |
221 | 223 | ||
222 | error = freeze_processes(); | 224 | error = freeze_processes(); |
223 | if (!error) | 225 | if (error) |
226 | break; | ||
227 | |||
228 | error = create_basic_memory_bitmaps(); | ||
229 | if (error) | ||
230 | thaw_processes(); | ||
231 | else | ||
224 | data->frozen = 1; | 232 | data->frozen = 1; |
233 | |||
225 | break; | 234 | break; |
226 | 235 | ||
227 | case SNAPSHOT_UNFREEZE: | 236 | case SNAPSHOT_UNFREEZE: |
228 | if (!data->frozen || data->ready) | 237 | if (!data->frozen || data->ready) |
229 | break; | 238 | break; |
230 | pm_restore_gfp_mask(); | 239 | pm_restore_gfp_mask(); |
240 | free_basic_memory_bitmaps(); | ||
241 | data->free_bitmaps = false; | ||
231 | thaw_processes(); | 242 | thaw_processes(); |
232 | data->frozen = 0; | 243 | data->frozen = 0; |
233 | break; | 244 | break; |
@@ -371,6 +382,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
371 | 382 | ||
372 | } | 383 | } |
373 | 384 | ||
385 | unlock_device_hotplug(); | ||
374 | mutex_unlock(&pm_mutex); | 386 | mutex_unlock(&pm_mutex); |
375 | 387 | ||
376 | return error; | 388 | return error; |