summaryrefslogtreecommitdiffstats
path: root/kernel/power/snapshot.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-06-28 21:02:16 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-07-01 19:52:09 -0400
commit6dbecfd345a617888da370b13d5b190c9ff3df53 (patch)
tree65fdd1cdec7c217d5b2ff8fe591624110bd03c51 /kernel/power/snapshot.c
parent9c744481c003697de453e8fc039468143ba604aa (diff)
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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r--kernel/power/snapshot.c64
1 files changed, 25 insertions, 39 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index d9476ff877b8..39bbad5fac5a 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -2019,53 +2019,41 @@ int snapshot_read_next(struct snapshot_handle *handle)
2019 return PAGE_SIZE; 2019 return PAGE_SIZE;
2020} 2020}
2021 2021
2022static void duplicate_memory_bitmap(struct memory_bitmap *dst,
2023 struct memory_bitmap *src)
2024{
2025 unsigned long pfn;
2026
2027 memory_bm_position_reset(src);
2028 pfn = memory_bm_next_pfn(src);
2029 while (pfn != BM_END_OF_MAP) {
2030 memory_bm_set_bit(dst, pfn);
2031 pfn = memory_bm_next_pfn(src);
2032 }
2033}
2034
2022/** 2035/**
2023 * mark_unsafe_pages - mark the pages that cannot be used for storing 2036 * mark_unsafe_pages - mark the pages that cannot be used for storing
2024 * the image during resume, because they conflict with the pages that 2037 * the image during resume, because they conflict with the pages that
2025 * had been used before suspend 2038 * had been used before suspend
2026 */ 2039 */
2027 2040
2028static int mark_unsafe_pages(struct memory_bitmap *bm) 2041static void mark_unsafe_pages(struct memory_bitmap *bm)
2029{ 2042{
2030 struct zone *zone; 2043 unsigned long pfn;
2031 unsigned long pfn, max_zone_pfn;
2032 2044
2033 /* Clear page flags */ 2045 /* Clear the "free"/"unsafe" bit for all PFNs */
2034 for_each_populated_zone(zone) { 2046 memory_bm_position_reset(free_pages_map);
2035 max_zone_pfn = zone_end_pfn(zone); 2047 pfn = memory_bm_next_pfn(free_pages_map);
2036 for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) 2048 while (pfn != BM_END_OF_MAP) {
2037 if (pfn_valid(pfn)) 2049 memory_bm_clear_current(free_pages_map);
2038 swsusp_unset_page_free(pfn_to_page(pfn)); 2050 pfn = memory_bm_next_pfn(free_pages_map);
2039 } 2051 }
2040 2052
2041 /* Mark pages that correspond to the "original" pfns as "unsafe" */ 2053 /* Mark pages that correspond to the "original" PFNs as "unsafe" */
2042 memory_bm_position_reset(bm); 2054 duplicate_memory_bitmap(free_pages_map, bm);
2043 do {
2044 pfn = memory_bm_next_pfn(bm);
2045 if (likely(pfn != BM_END_OF_MAP)) {
2046 if (likely(pfn_valid(pfn)))
2047 swsusp_set_page_free(pfn_to_page(pfn));
2048 else
2049 return -EFAULT;
2050 }
2051 } while (pfn != BM_END_OF_MAP);
2052 2055
2053 allocated_unsafe_pages = 0; 2056 allocated_unsafe_pages = 0;
2054
2055 return 0;
2056}
2057
2058static void
2059duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
2060{
2061 unsigned long pfn;
2062
2063 memory_bm_position_reset(src);
2064 pfn = memory_bm_next_pfn(src);
2065 while (pfn != BM_END_OF_MAP) {
2066 memory_bm_set_bit(dst, pfn);
2067 pfn = memory_bm_next_pfn(src);
2068 }
2069} 2057}
2070 2058
2071static int check_header(struct swsusp_info *info) 2059static int check_header(struct swsusp_info *info)
@@ -2115,7 +2103,7 @@ static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
2115 /* Extract and buffer page key for data page (s390 only). */ 2103 /* Extract and buffer page key for data page (s390 only). */
2116 page_key_memorize(buf + j); 2104 page_key_memorize(buf + j);
2117 2105
2118 if (memory_bm_pfn_present(bm, buf[j])) 2106 if (pfn_valid(buf[j]) && memory_bm_pfn_present(bm, buf[j]))
2119 memory_bm_set_bit(bm, buf[j]); 2107 memory_bm_set_bit(bm, buf[j]);
2120 else 2108 else
2121 return -EFAULT; 2109 return -EFAULT;
@@ -2357,9 +2345,7 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
2357 buffer = NULL; 2345 buffer = NULL;
2358 2346
2359 nr_highmem = count_highmem_image_pages(bm); 2347 nr_highmem = count_highmem_image_pages(bm);
2360 error = mark_unsafe_pages(bm); 2348 mark_unsafe_pages(bm);
2361 if (error)
2362 goto Free;
2363 2349
2364 error = memory_bm_create(new_bm, GFP_ATOMIC, PG_SAFE); 2350 error = memory_bm_create(new_bm, GFP_ATOMIC, PG_SAFE);
2365 if (error) 2351 if (error)