Commit 6dbecfd3 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

PM / hibernate: Simplify mark_unsafe_pages()

Rework mark_unsafe_pages() to use a simpler method of clearing
all bits in free_pages_map and to set the bits for the "unsafe"
pages (ie. pages that were used by the image kernel before
hibernation) with the help of duplicate_memory_bitmap().

For this purpose, move the pfn_valid() check from mark_unsafe_pages()
to unpack_orig_pfns() where the "unsafe" pages are discovered.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 9c744481
...@@ -2019,53 +2019,41 @@ int snapshot_read_next(struct snapshot_handle *handle) ...@@ -2019,53 +2019,41 @@ int snapshot_read_next(struct snapshot_handle *handle)
return PAGE_SIZE; return PAGE_SIZE;
} }
static void duplicate_memory_bitmap(struct memory_bitmap *dst,
struct memory_bitmap *src)
{
unsigned long pfn;
memory_bm_position_reset(src);
pfn = memory_bm_next_pfn(src);
while (pfn != BM_END_OF_MAP) {
memory_bm_set_bit(dst, pfn);
pfn = memory_bm_next_pfn(src);
}
}
/** /**
* mark_unsafe_pages - mark the pages that cannot be used for storing * mark_unsafe_pages - mark the pages that cannot be used for storing
* the image during resume, because they conflict with the pages that * the image during resume, because they conflict with the pages that
* had been used before suspend * had been used before suspend
*/ */
static int mark_unsafe_pages(struct memory_bitmap *bm) static void mark_unsafe_pages(struct memory_bitmap *bm)
{ {
struct zone *zone; unsigned long pfn;
unsigned long pfn, max_zone_pfn;
/* Clear page flags */ /* Clear the "free"/"unsafe" bit for all PFNs */
for_each_populated_zone(zone) { memory_bm_position_reset(free_pages_map);
max_zone_pfn = zone_end_pfn(zone); pfn = memory_bm_next_pfn(free_pages_map);
for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) while (pfn != BM_END_OF_MAP) {
if (pfn_valid(pfn)) memory_bm_clear_current(free_pages_map);
swsusp_unset_page_free(pfn_to_page(pfn)); pfn = memory_bm_next_pfn(free_pages_map);
} }
/* Mark pages that correspond to the "original" pfns as "unsafe" */ /* Mark pages that correspond to the "original" PFNs as "unsafe" */
memory_bm_position_reset(bm); duplicate_memory_bitmap(free_pages_map, bm);
do {
pfn = memory_bm_next_pfn(bm);
if (likely(pfn != BM_END_OF_MAP)) {
if (likely(pfn_valid(pfn)))
swsusp_set_page_free(pfn_to_page(pfn));
else
return -EFAULT;
}
} while (pfn != BM_END_OF_MAP);
allocated_unsafe_pages = 0; allocated_unsafe_pages = 0;
return 0;
}
static void
duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
{
unsigned long pfn;
memory_bm_position_reset(src);
pfn = memory_bm_next_pfn(src);
while (pfn != BM_END_OF_MAP) {
memory_bm_set_bit(dst, pfn);
pfn = memory_bm_next_pfn(src);
}
} }
static int check_header(struct swsusp_info *info) static int check_header(struct swsusp_info *info)
...@@ -2115,7 +2103,7 @@ static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) ...@@ -2115,7 +2103,7 @@ static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
/* Extract and buffer page key for data page (s390 only). */ /* Extract and buffer page key for data page (s390 only). */
page_key_memorize(buf + j); page_key_memorize(buf + j);
if (memory_bm_pfn_present(bm, buf[j])) if (pfn_valid(buf[j]) && memory_bm_pfn_present(bm, buf[j]))
memory_bm_set_bit(bm, buf[j]); memory_bm_set_bit(bm, buf[j]);
else else
return -EFAULT; return -EFAULT;
...@@ -2357,9 +2345,7 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) ...@@ -2357,9 +2345,7 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
buffer = NULL; buffer = NULL;
nr_highmem = count_highmem_image_pages(bm); nr_highmem = count_highmem_image_pages(bm);
error = mark_unsafe_pages(bm); mark_unsafe_pages(bm);
if (error)
goto Free;
error = memory_bm_create(new_bm, GFP_ATOMIC, PG_SAFE); error = memory_bm_create(new_bm, GFP_ATOMIC, PG_SAFE);
if (error) if (error)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment