diff options
| author | Patrick Mochel <mochel@osdl.org> | 2003-09-16 03:48:21 -0700 |
|---|---|---|
| committer | Patrick Mochel <mochel@osdl.org> | 2003-09-16 03:48:21 -0700 |
| commit | f50de96102f209f1707275ff1d0a1427d4b94cbd (patch) | |
| tree | b01665058b3c71db871aaa527793a99456a775c2 /kernel | |
| parent | d9b9312170ec455722d5ff52ae58e28267c6e88d (diff) | |
[power] Clean up pmdisk page freeing
- Fix small buglet when freeing image pages on resume where we were only
freeing the first (1 << pagedir_order) (e.g. 16) pages, instead of all
of them.
- Make sure we save the page directory, which requires an update of the total
number of pages to save, and requires that we don't mark those pages as
unsaveable.
- Restore __GFP_COLD flag to allocations.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/pmdisk.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/kernel/power/pmdisk.c b/kernel/power/pmdisk.c index 58db2d8f1090..97e6dc4bb06f 100644 --- a/kernel/power/pmdisk.c +++ b/kernel/power/pmdisk.c @@ -496,10 +496,9 @@ static void copy_pages(void) static void free_image_pages(void) { struct pbe * p; - int i, n; + int i; - n = 1 << pagedir_order; - for (i = 0, p = pagedir_save; i < n; i++, p++) { + for (i = 0, p = pagedir_save; i < pmdisk_pages; i++, p++) { ClearPageNosave(virt_to_page(p->address)); free_page(p->address); } @@ -517,6 +516,24 @@ static void free_pagedir(void) } +static void calc_order(void) +{ + int diff; + int order; + + order = get_bitmask_order(SUSPEND_PD_PAGES(pmdisk_pages)); + pmdisk_pages += 1 << order; + do { + diff = get_bitmask_order(SUSPEND_PD_PAGES(pmdisk_pages)) - order; + if (diff) { + order += diff; + pmdisk_pages += 1 << diff; + } + } while(diff); + pagedir_order = order; +} + + /** * alloc_pagedir - Allocate the page directory. * @@ -526,19 +543,12 @@ static void free_pagedir(void) static int alloc_pagedir(void) { - struct page *page; - int i, n; - - pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(pmdisk_pages)); - n = 1 << pagedir_order; - - pagedir_save = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, + calc_order(); + pagedir_save = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_order); if(!pagedir_save) return -ENOMEM; - memset(pagedir_save,0,n * PAGE_SIZE); - for(i = 0, page = virt_to_page(pagedir_save); i < n; i++, page++) - SetPageNosave(page); + memset(pagedir_save,0,(1 << pagedir_order) * PAGE_SIZE); pm_pagedir_nosave = pagedir_save; return 0; } @@ -555,7 +565,7 @@ static int alloc_image_pages(void) int i; for (i = 0, p = pagedir_save; i < pmdisk_pages; i++, p++) { - p->address = get_zeroed_page(GFP_ATOMIC); + p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD); if(!p->address) goto Error; SetPageNosave(virt_to_page(p->address)); |
