diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-28 21:02:16 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-07-01 19:52:09 -0400 |
commit | 6dbecfd345a617888da370b13d5b190c9ff3df53 (patch) | |
tree | 65fdd1cdec7c217d5b2ff8fe591624110bd03c51 /kernel/power/snapshot.c | |
parent | 9c744481c003697de453e8fc039468143ba604aa (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.c | 64 |
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 | ||
2022 | static 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 | ||
2028 | static int mark_unsafe_pages(struct memory_bitmap *bm) | 2041 | static 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 | |||
2058 | static void | ||
2059 | duplicate_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 | ||
2071 | static int check_header(struct swsusp_info *info) | 2059 | 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 | /* 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) |