aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r--kernel/power/snapshot.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 723f5179883e..4a6dbcefd378 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -88,8 +88,7 @@ static int save_highmem_zone(struct zone *zone)
88 return 0; 88 return 0;
89} 89}
90 90
91 91int save_highmem(void)
92static int save_highmem(void)
93{ 92{
94 struct zone *zone; 93 struct zone *zone;
95 int res = 0; 94 int res = 0;
@@ -120,11 +119,7 @@ int restore_highmem(void)
120 } 119 }
121 return 0; 120 return 0;
122} 121}
123#else 122#endif
124static int save_highmem(void) { return 0; }
125int restore_highmem(void) { return 0; }
126#endif /* CONFIG_HIGHMEM */
127
128 123
129static int pfn_is_nosave(unsigned long pfn) 124static int pfn_is_nosave(unsigned long pfn)
130{ 125{
@@ -216,7 +211,7 @@ static void copy_data_pages(struct pbe *pblist)
216 * free_pagedir - free pages allocated with alloc_pagedir() 211 * free_pagedir - free pages allocated with alloc_pagedir()
217 */ 212 */
218 213
219static void free_pagedir(struct pbe *pblist) 214void free_pagedir(struct pbe *pblist)
220{ 215{
221 struct pbe *pbe; 216 struct pbe *pbe;
222 217
@@ -269,9 +264,30 @@ void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
269 pr_debug("create_pbe_list(): initialized %d PBEs\n", num); 264 pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
270} 265}
271 266
272static void *alloc_image_page(void) 267/**
268 * @safe_needed - on resume, for storing the PBE list and the image,
269 * we can only use memory pages that do not conflict with the pages
270 * which had been used before suspend.
271 *
272 * The unsafe pages are marked with the PG_nosave_free flag
273 *
274 * Allocated but unusable (ie eaten) memory pages should be marked
275 * so that swsusp_free() can release them
276 */
277
278static inline void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
273{ 279{
274 void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD); 280 void *res;
281
282 if (safe_needed)
283 do {
284 res = (void *)get_zeroed_page(gfp_mask);
285 if (res && PageNosaveFree(virt_to_page(res)))
286 /* This is for swsusp_free() */
287 SetPageNosave(virt_to_page(res));
288 } while (res && PageNosaveFree(virt_to_page(res)));
289 else
290 res = (void *)get_zeroed_page(gfp_mask);
275 if (res) { 291 if (res) {
276 SetPageNosave(virt_to_page(res)); 292 SetPageNosave(virt_to_page(res));
277 SetPageNosaveFree(virt_to_page(res)); 293 SetPageNosaveFree(virt_to_page(res));
@@ -279,6 +295,11 @@ static void *alloc_image_page(void)
279 return res; 295 return res;
280} 296}
281 297
298unsigned long get_safe_page(gfp_t gfp_mask)
299{
300 return (unsigned long)alloc_image_page(gfp_mask, 1);
301}
302
282/** 303/**
283 * alloc_pagedir - Allocate the page directory. 304 * alloc_pagedir - Allocate the page directory.
284 * 305 *
@@ -292,7 +313,7 @@ static void *alloc_image_page(void)
292 * On each page we set up a list of struct_pbe elements. 313 * On each page we set up a list of struct_pbe elements.
293 */ 314 */
294 315
295struct pbe *alloc_pagedir(unsigned int nr_pages) 316struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed)
296{ 317{
297 unsigned int num; 318 unsigned int num;
298 struct pbe *pblist, *pbe; 319 struct pbe *pblist, *pbe;
@@ -301,12 +322,12 @@ struct pbe *alloc_pagedir(unsigned int nr_pages)
301 return NULL; 322 return NULL;
302 323
303 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages); 324 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
304 pblist = alloc_image_page(); 325 pblist = alloc_image_page(gfp_mask, safe_needed);
305 /* FIXME: rewrite this ugly loop */ 326 /* FIXME: rewrite this ugly loop */
306 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages; 327 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
307 pbe = pbe->next, num += PBES_PER_PAGE) { 328 pbe = pbe->next, num += PBES_PER_PAGE) {
308 pbe += PB_PAGE_SKIP; 329 pbe += PB_PAGE_SKIP;
309 pbe->next = alloc_image_page(); 330 pbe->next = alloc_image_page(gfp_mask, safe_needed);
310 } 331 }
311 if (!pbe) { /* get_zeroed_page() failed */ 332 if (!pbe) { /* get_zeroed_page() failed */
312 free_pagedir(pblist); 333 free_pagedir(pblist);
@@ -354,24 +375,32 @@ static int enough_free_mem(unsigned int nr_pages)
354 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); 375 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
355} 376}
356 377
378int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
379{
380 struct pbe *p;
381
382 for_each_pbe (p, pblist) {
383 p->address = (unsigned long)alloc_image_page(gfp_mask, safe_needed);
384 if (!p->address)
385 return -ENOMEM;
386 }
387 return 0;
388}
357 389
358static struct pbe *swsusp_alloc(unsigned int nr_pages) 390static struct pbe *swsusp_alloc(unsigned int nr_pages)
359{ 391{
360 struct pbe *pblist, *p; 392 struct pbe *pblist;
361 393
362 if (!(pblist = alloc_pagedir(nr_pages))) { 394 if (!(pblist = alloc_pagedir(nr_pages, GFP_ATOMIC | __GFP_COLD, 0))) {
363 printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); 395 printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
364 return NULL; 396 return NULL;
365 } 397 }
366 create_pbe_list(pblist, nr_pages); 398 create_pbe_list(pblist, nr_pages);
367 399
368 for_each_pbe (p, pblist) { 400 if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
369 p->address = (unsigned long)alloc_image_page(); 401 printk(KERN_ERR "suspend: Allocating image pages failed.\n");
370 if (!p->address) { 402 swsusp_free();
371 printk(KERN_ERR "suspend: Allocating image pages failed.\n"); 403 return NULL;
372 swsusp_free();
373 return NULL;
374 }
375 } 404 }
376 405
377 return pblist; 406 return pblist;
@@ -382,11 +411,6 @@ asmlinkage int swsusp_save(void)
382 unsigned int nr_pages; 411 unsigned int nr_pages;
383 412
384 pr_debug("swsusp: critical section: \n"); 413 pr_debug("swsusp: critical section: \n");
385 if (save_highmem()) {
386 printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
387 restore_highmem();
388 return -ENOMEM;
389 }
390 414
391 drain_local_pages(); 415 drain_local_pages();
392 nr_pages = count_data_pages(); 416 nr_pages = count_data_pages();
@@ -406,11 +430,6 @@ asmlinkage int swsusp_save(void)
406 return -ENOMEM; 430 return -ENOMEM;
407 } 431 }
408 432
409 if (!enough_swap(nr_pages)) {
410 printk(KERN_ERR "swsusp: Not enough free swap\n");
411 return -ENOSPC;
412 }
413
414 pagedir_nosave = swsusp_alloc(nr_pages); 433 pagedir_nosave = swsusp_alloc(nr_pages);
415 if (!pagedir_nosave) 434 if (!pagedir_nosave)
416 return -ENOMEM; 435 return -ENOMEM;