aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-05-06 17:50:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:12:59 -0400
commit0709db6072c2e799eba1aa61bd19e0d7f38aa2cd (patch)
treee348c73adbfdcb46b05b23f36dc420ecdd62ca8a /kernel/power
parent1525a2ad76f991eba9755f75c9b6d4d97abad25e (diff)
swsusp: use GFP_KERNEL for creating basic data structures
Make swsusp call create_basic_memory_bitmaps() before processes are frozen, so that GFP_KERNEL allocations can be made in it. Additionally, ensure that the swsusp's userland interface won't be used while either pm_suspend_disk() or software_resume() is being executed. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/disk.c37
-rw-r--r--kernel/power/power.h3
-rw-r--r--kernel/power/snapshot.c8
-rw-r--r--kernel/power/user.c10
4 files changed, 38 insertions, 20 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 403bc3722fee..e518379b667a 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -130,28 +130,33 @@ int pm_suspend_disk(void)
130{ 130{
131 int error; 131 int error;
132 132
133 /* The snapshot device should not be opened while we're running */
134 if (!atomic_add_unless(&snapshot_device_available, -1, 0))
135 return -EBUSY;
136
137 /* Allocate memory management structures */
138 error = create_basic_memory_bitmaps();
139 if (error)
140 goto Exit;
141
133 error = prepare_processes(); 142 error = prepare_processes();
134 if (error) 143 if (error)
135 return error; 144 goto Finish;
136 145
137 if (pm_disk_mode == PM_DISK_TESTPROC) { 146 if (pm_disk_mode == PM_DISK_TESTPROC) {
138 printk("swsusp debug: Waiting for 5 seconds.\n"); 147 printk("swsusp debug: Waiting for 5 seconds.\n");
139 mdelay(5000); 148 mdelay(5000);
140 goto Thaw; 149 goto Thaw;
141 } 150 }
142 /* Allocate memory management structures */
143 error = create_basic_memory_bitmaps();
144 if (error)
145 goto Thaw;
146 151
147 /* Free memory before shutting down devices. */ 152 /* Free memory before shutting down devices. */
148 error = swsusp_shrink_memory(); 153 error = swsusp_shrink_memory();
149 if (error) 154 if (error)
150 goto Finish; 155 goto Thaw;
151 156
152 error = platform_prepare(); 157 error = platform_prepare();
153 if (error) 158 if (error)
154 goto Finish; 159 goto Thaw;
155 160
156 suspend_console(); 161 suspend_console();
157 error = device_suspend(PMSG_FREEZE); 162 error = device_suspend(PMSG_FREEZE);
@@ -186,7 +191,7 @@ int pm_suspend_disk(void)
186 power_down(); 191 power_down();
187 else { 192 else {
188 swsusp_free(); 193 swsusp_free();
189 goto Finish; 194 goto Thaw;
190 } 195 }
191 } else { 196 } else {
192 pr_debug("PM: Image restored successfully.\n"); 197 pr_debug("PM: Image restored successfully.\n");
@@ -199,10 +204,12 @@ int pm_suspend_disk(void)
199 platform_finish(); 204 platform_finish();
200 device_resume(); 205 device_resume();
201 resume_console(); 206 resume_console();
202 Finish:
203 free_basic_memory_bitmaps();
204 Thaw: 207 Thaw:
205 unprepare_processes(); 208 unprepare_processes();
209 Finish:
210 free_basic_memory_bitmaps();
211 Exit:
212 atomic_inc(&snapshot_device_available);
206 return error; 213 return error;
207} 214}
208 215
@@ -250,9 +257,15 @@ static int software_resume(void)
250 if (error) 257 if (error)
251 goto Unlock; 258 goto Unlock;
252 259
260 /* The snapshot device should not be opened while we're running */
261 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
262 error = -EBUSY;
263 goto Unlock;
264 }
265
253 error = create_basic_memory_bitmaps(); 266 error = create_basic_memory_bitmaps();
254 if (error) 267 if (error)
255 goto Unlock; 268 goto Finish;
256 269
257 pr_debug("PM: Preparing processes for restore.\n"); 270 pr_debug("PM: Preparing processes for restore.\n");
258 error = prepare_processes(); 271 error = prepare_processes();
@@ -290,6 +303,8 @@ static int software_resume(void)
290 unprepare_processes(); 303 unprepare_processes();
291 Done: 304 Done:
292 free_basic_memory_bitmaps(); 305 free_basic_memory_bitmaps();
306 Finish:
307 atomic_inc(&snapshot_device_available);
293 /* For success case, the suspend path will release the lock */ 308 /* For success case, the suspend path will release the lock */
294 Unlock: 309 Unlock:
295 mutex_unlock(&pm_mutex); 310 mutex_unlock(&pm_mutex);
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 1f8052bda0f7..a64d3f22de97 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -140,6 +140,9 @@ struct resume_swap_area {
140#define PMOPS_ENTER 2 140#define PMOPS_ENTER 2
141#define PMOPS_FINISH 3 141#define PMOPS_FINISH 3
142 142
143/* If unset, the snapshot device cannot be open. */
144extern atomic_t snapshot_device_available;
145
143/** 146/**
144 * The bitmap is used for tracing allocated swap pages 147 * The bitmap is used for tracing allocated swap pages
145 * 148 *
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index f66e4411795b..128da11f01c2 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -723,19 +723,19 @@ int create_basic_memory_bitmaps(void)
723 723
724 BUG_ON(forbidden_pages_map || free_pages_map); 724 BUG_ON(forbidden_pages_map || free_pages_map);
725 725
726 bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_ATOMIC); 726 bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL);
727 if (!bm1) 727 if (!bm1)
728 return -ENOMEM; 728 return -ENOMEM;
729 729
730 error = memory_bm_create(bm1, GFP_ATOMIC | __GFP_COLD, PG_ANY); 730 error = memory_bm_create(bm1, GFP_KERNEL, PG_ANY);
731 if (error) 731 if (error)
732 goto Free_first_object; 732 goto Free_first_object;
733 733
734 bm2 = kzalloc(sizeof(struct memory_bitmap), GFP_ATOMIC); 734 bm2 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL);
735 if (!bm2) 735 if (!bm2)
736 goto Free_first_bitmap; 736 goto Free_first_bitmap;
737 737
738 error = memory_bm_create(bm2, GFP_ATOMIC | __GFP_COLD, PG_ANY); 738 error = memory_bm_create(bm2, GFP_KERNEL, PG_ANY);
739 if (error) 739 if (error)
740 goto Free_second_object; 740 goto Free_second_object;
741 741
diff --git a/kernel/power/user.c b/kernel/power/user.c
index bd1771f7a64e..72dbfd01408e 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -40,21 +40,21 @@ static struct snapshot_data {
40 char platform_suspend; 40 char platform_suspend;
41} snapshot_state; 41} snapshot_state;
42 42
43static atomic_t device_available = ATOMIC_INIT(1); 43atomic_t snapshot_device_available = ATOMIC_INIT(1);
44 44
45static int snapshot_open(struct inode *inode, struct file *filp) 45static int snapshot_open(struct inode *inode, struct file *filp)
46{ 46{
47 struct snapshot_data *data; 47 struct snapshot_data *data;
48 48
49 if (!atomic_add_unless(&device_available, -1, 0)) 49 if (!atomic_add_unless(&snapshot_device_available, -1, 0))
50 return -EBUSY; 50 return -EBUSY;
51 51
52 if ((filp->f_flags & O_ACCMODE) == O_RDWR) { 52 if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
53 atomic_inc(&device_available); 53 atomic_inc(&snapshot_device_available);
54 return -ENOSYS; 54 return -ENOSYS;
55 } 55 }
56 if(create_basic_memory_bitmaps()) { 56 if(create_basic_memory_bitmaps()) {
57 atomic_inc(&device_available); 57 atomic_inc(&snapshot_device_available);
58 return -ENOMEM; 58 return -ENOMEM;
59 } 59 }
60 nonseekable_open(inode, filp); 60 nonseekable_open(inode, filp);
@@ -92,7 +92,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
92 enable_nonboot_cpus(); 92 enable_nonboot_cpus();
93 mutex_unlock(&pm_mutex); 93 mutex_unlock(&pm_mutex);
94 } 94 }
95 atomic_inc(&device_available); 95 atomic_inc(&snapshot_device_available);
96 return 0; 96 return 0;
97} 97}
98 98