aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2006-09-26 02:32:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:49:02 -0400
commit940864ddabdb180e02041c4dcd46ba6f9eee732f (patch)
treecee174e45717dce64f7108a1c74182e691c1c8c2 /kernel/power
parentb788db79896ef2a5817b9395ad63573b254a6d93 (diff)
[PATCH] swsusp: Use memory bitmaps during resume
Make swsusp use memory bitmaps to store its internal information during the resume phase of the suspend-resume cycle. If the pfns of saveable pages are saved during the suspend phase instead of the kernel virtual addresses of these pages, we can use them during the resume phase directly to set the corresponding bits in a memory bitmap. Then, this bitmap is used to mark the page frames corresponding to the pages that were saveable before the suspend (aka "unsafe" page frames). Next, we allocate as many page frames as needed to store the entire suspend image and make sure that there will be some extra free "safe" page frames for the list of PBEs constructed later. Subsequently, the image is loaded and, if possible, the data loaded from it are written into their "original" page frames (ie. the ones they had occupied before the suspend). The image data that cannot be written into their "original" page frames are loaded into "safe" page frames and their "original" kernel virtual addresses, as well as the addresses of the "safe" pages containing their copies, are stored in a list of PBEs. Finally, the list of PBEs is used to copy the remaining image data into their "original" page frames (this is done atomically, by the architecture-dependent parts of swsusp). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/power.h11
-rw-r--r--kernel/power/snapshot.c416
-rw-r--r--kernel/power/swap.c4
-rw-r--r--kernel/power/user.c1
4 files changed, 186 insertions, 246 deletions
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 6e9e2acc34f8..bfe999f7b272 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -81,16 +81,6 @@ struct snapshot_handle {
81 unsigned int prev; /* number of the block of PAGE_SIZE bytes that 81 unsigned int prev; /* number of the block of PAGE_SIZE bytes that
82 * was the current one previously 82 * was the current one previously
83 */ 83 */
84 struct pbe *pbe; /* PBE that corresponds to 'buffer' */
85 struct pbe *last_pbe; /* When the image is restored (eg. read
86 * from disk) we can store some image
87 * data directly in the page frames
88 * in which they were before suspend.
89 * In such a case the PBEs that
90 * correspond to them will be unused.
91 * This is the last PBE, so far, that
92 * does not correspond to such data.
93 */
94 void *buffer; /* address of the block to read from 84 void *buffer; /* address of the block to read from
95 * or write to 85 * or write to
96 */ 86 */
@@ -113,6 +103,7 @@ extern unsigned int snapshot_additional_pages(struct zone *zone);
113extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); 103extern int snapshot_read_next(struct snapshot_handle *handle, size_t count);
114extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); 104extern int snapshot_write_next(struct snapshot_handle *handle, size_t count);
115extern int snapshot_image_loaded(struct snapshot_handle *handle); 105extern int snapshot_image_loaded(struct snapshot_handle *handle);
106extern void snapshot_free_unused_memory(struct snapshot_handle *handle);
116 107
117#define SNAPSHOT_IOC_MAGIC '3' 108#define SNAPSHOT_IOC_MAGIC '3'
118#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) 109#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1)
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 852e0df41719..1b84313cbab5 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -39,7 +39,7 @@ struct pbe *restore_pblist;
39 39
40static unsigned int nr_copy_pages; 40static unsigned int nr_copy_pages;
41static unsigned int nr_meta_pages; 41static unsigned int nr_meta_pages;
42static unsigned long *buffer; 42static void *buffer;
43 43
44#ifdef CONFIG_HIGHMEM 44#ifdef CONFIG_HIGHMEM
45unsigned int count_highmem_pages(void) 45unsigned int count_highmem_pages(void)
@@ -172,7 +172,7 @@ static inline int restore_highmem(void) {return 0;}
172#define PG_UNSAFE_CLEAR 1 172#define PG_UNSAFE_CLEAR 1
173#define PG_UNSAFE_KEEP 0 173#define PG_UNSAFE_KEEP 0
174 174
175static unsigned int unsafe_pages; 175static unsigned int allocated_unsafe_pages;
176 176
177static void *alloc_image_page(gfp_t gfp_mask, int safe_needed) 177static void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
178{ 178{
@@ -183,7 +183,7 @@ static void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
183 while (res && PageNosaveFree(virt_to_page(res))) { 183 while (res && PageNosaveFree(virt_to_page(res))) {
184 /* The page is unsafe, mark it for swsusp_free() */ 184 /* The page is unsafe, mark it for swsusp_free() */
185 SetPageNosave(virt_to_page(res)); 185 SetPageNosave(virt_to_page(res));
186 unsafe_pages++; 186 allocated_unsafe_pages++;
187 res = (void *)get_zeroed_page(gfp_mask); 187 res = (void *)get_zeroed_page(gfp_mask);
188 } 188 }
189 if (res) { 189 if (res) {
@@ -772,101 +772,10 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
772} 772}
773 773
774/** 774/**
775 * free_pagedir - free pages allocated with alloc_pagedir() 775 * swsusp_free - free pages allocated for the suspend.
776 */
777
778static void free_pagedir(struct pbe *pblist, int clear_nosave_free)
779{
780 struct pbe *pbe;
781
782 while (pblist) {
783 pbe = (pblist + PB_PAGE_SKIP)->next;
784 free_image_page(pblist, clear_nosave_free);
785 pblist = pbe;
786 }
787}
788
789/**
790 * fill_pb_page - Create a list of PBEs on a given memory page
791 */
792
793static inline void fill_pb_page(struct pbe *pbpage, unsigned int n)
794{
795 struct pbe *p;
796
797 p = pbpage;
798 pbpage += n - 1;
799 do
800 p->next = p + 1;
801 while (++p < pbpage);
802}
803
804/**
805 * create_pbe_list - Create a list of PBEs on top of a given chain
806 * of memory pages allocated with alloc_pagedir()
807 * 776 *
808 * This function assumes that pages allocated by alloc_image_page() will 777 * Suspend pages are alocated before the atomic copy is made, so we
809 * always be zeroed. 778 * need to release them after the resume.
810 */
811
812static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
813{
814 struct pbe *pbpage;
815 unsigned int num = PBES_PER_PAGE;
816
817 for_each_pb_page (pbpage, pblist) {
818 if (num >= nr_pages)
819 break;
820
821 fill_pb_page(pbpage, PBES_PER_PAGE);
822 num += PBES_PER_PAGE;
823 }
824 if (pbpage) {
825 num -= PBES_PER_PAGE;
826 fill_pb_page(pbpage, nr_pages - num);
827 }
828}
829
830/**
831 * alloc_pagedir - Allocate the page directory.
832 *
833 * First, determine exactly how many pages we need and
834 * allocate them.
835 *
836 * We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
837 * struct pbe elements (pbes) and the last element in the page points
838 * to the next page.
839 *
840 * On each page we set up a list of struct_pbe elements.
841 */
842
843static struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask,
844 int safe_needed)
845{
846 unsigned int num;
847 struct pbe *pblist, *pbe;
848
849 if (!nr_pages)
850 return NULL;
851
852 pblist = alloc_image_page(gfp_mask, safe_needed);
853 pbe = pblist;
854 for (num = PBES_PER_PAGE; num < nr_pages; num += PBES_PER_PAGE) {
855 if (!pbe) {
856 free_pagedir(pblist, PG_UNSAFE_CLEAR);
857 return NULL;
858 }
859 pbe += PB_PAGE_SKIP;
860 pbe->next = alloc_image_page(gfp_mask, safe_needed);
861 pbe = pbe->next;
862 }
863 create_pbe_list(pblist, nr_pages);
864 return pblist;
865}
866
867/**
868 * Free pages we allocated for suspend. Suspend pages are alocated
869 * before atomic copy, so we need to free them after resume.
870 */ 779 */
871 780
872void swsusp_free(void) 781void swsusp_free(void)
@@ -904,14 +813,18 @@ void swsusp_free(void)
904static int enough_free_mem(unsigned int nr_pages) 813static int enough_free_mem(unsigned int nr_pages)
905{ 814{
906 struct zone *zone; 815 struct zone *zone;
907 unsigned int n = 0; 816 unsigned int free = 0, meta = 0;
908 817
909 for_each_zone (zone) 818 for_each_zone (zone)
910 if (!is_highmem(zone)) 819 if (!is_highmem(zone)) {
911 n += zone->free_pages; 820 free += zone->free_pages;
912 pr_debug("swsusp: available memory: %u pages\n", n); 821 meta += snapshot_additional_pages(zone);
913 return n > (nr_pages + PAGES_FOR_IO + 822 }
914 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); 823
824 pr_debug("swsusp: pages needed: %u + %u + %u, available pages: %u\n",
825 nr_pages, PAGES_FOR_IO, meta, free);
826
827 return free > nr_pages + PAGES_FOR_IO + meta;
915} 828}
916 829
917static int 830static int
@@ -961,11 +874,6 @@ asmlinkage int swsusp_save(void)
961 nr_pages = count_data_pages(); 874 nr_pages = count_data_pages();
962 printk("swsusp: Need to copy %u pages\n", nr_pages); 875 printk("swsusp: Need to copy %u pages\n", nr_pages);
963 876
964 pr_debug("swsusp: pages needed: %u + %lu + %u, free: %u\n",
965 nr_pages,
966 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
967 PAGES_FOR_IO, nr_free_pages());
968
969 if (!enough_free_mem(nr_pages)) { 877 if (!enough_free_mem(nr_pages)) {
970 printk(KERN_ERR "swsusp: Not enough free memory\n"); 878 printk(KERN_ERR "swsusp: Not enough free memory\n");
971 return -ENOMEM; 879 return -ENOMEM;
@@ -1007,22 +915,19 @@ static void init_header(struct swsusp_info *info)
1007} 915}
1008 916
1009/** 917/**
1010 * pack_addresses - the addresses corresponding to pfns found in the 918 * pack_pfns - pfns corresponding to the set bits found in the bitmap @bm
1011 * bitmap @bm are stored in the array @buf[] (1 page) 919 * are stored in the array @buf[] (1 page at a time)
1012 */ 920 */
1013 921
1014static inline void 922static inline void
1015pack_addresses(unsigned long *buf, struct memory_bitmap *bm) 923pack_pfns(unsigned long *buf, struct memory_bitmap *bm)
1016{ 924{
1017 int j; 925 int j;
1018 926
1019 for (j = 0; j < PAGE_SIZE / sizeof(long); j++) { 927 for (j = 0; j < PAGE_SIZE / sizeof(long); j++) {
1020 unsigned long pfn = memory_bm_next_pfn(bm); 928 buf[j] = memory_bm_next_pfn(bm);
1021 929 if (unlikely(buf[j] == BM_END_OF_MAP))
1022 if (unlikely(pfn == BM_END_OF_MAP))
1023 break; 930 break;
1024
1025 buf[j] = (unsigned long)page_address(pfn_to_page(pfn));
1026 } 931 }
1027} 932}
1028 933
@@ -1068,7 +973,7 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count)
1068 if (handle->prev < handle->cur) { 973 if (handle->prev < handle->cur) {
1069 if (handle->cur <= nr_meta_pages) { 974 if (handle->cur <= nr_meta_pages) {
1070 memset(buffer, 0, PAGE_SIZE); 975 memset(buffer, 0, PAGE_SIZE);
1071 pack_addresses(buffer, &orig_bm); 976 pack_pfns(buffer, &orig_bm);
1072 } else { 977 } else {
1073 unsigned long pfn = memory_bm_next_pfn(&copy_bm); 978 unsigned long pfn = memory_bm_next_pfn(&copy_bm);
1074 979
@@ -1094,14 +999,10 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count)
1094 * had been used before suspend 999 * had been used before suspend
1095 */ 1000 */
1096 1001
1097static int mark_unsafe_pages(struct pbe *pblist) 1002static int mark_unsafe_pages(struct memory_bitmap *bm)
1098{ 1003{
1099 struct zone *zone; 1004 struct zone *zone;
1100 unsigned long pfn, max_zone_pfn; 1005 unsigned long pfn, max_zone_pfn;
1101 struct pbe *p;
1102
1103 if (!pblist) /* a sanity check */
1104 return -EINVAL;
1105 1006
1106 /* Clear page flags */ 1007 /* Clear page flags */
1107 for_each_zone (zone) { 1008 for_each_zone (zone) {
@@ -1111,30 +1012,37 @@ static int mark_unsafe_pages(struct pbe *pblist)
1111 ClearPageNosaveFree(pfn_to_page(pfn)); 1012 ClearPageNosaveFree(pfn_to_page(pfn));
1112 } 1013 }
1113 1014
1114 /* Mark orig addresses */ 1015 /* Mark pages that correspond to the "original" pfns as "unsafe" */
1115 for_each_pbe (p, pblist) { 1016 memory_bm_position_reset(bm);
1116 if (virt_addr_valid(p->orig_address)) 1017 do {
1117 SetPageNosaveFree(virt_to_page(p->orig_address)); 1018 pfn = memory_bm_next_pfn(bm);
1118 else 1019 if (likely(pfn != BM_END_OF_MAP)) {
1119 return -EFAULT; 1020 if (likely(pfn_valid(pfn)))
1120 } 1021 SetPageNosaveFree(pfn_to_page(pfn));
1022 else
1023 return -EFAULT;
1024 }
1025 } while (pfn != BM_END_OF_MAP);
1121 1026
1122 unsafe_pages = 0; 1027 allocated_unsafe_pages = 0;
1123 1028
1124 return 0; 1029 return 0;
1125} 1030}
1126 1031
1127static void copy_page_backup_list(struct pbe *dst, struct pbe *src) 1032static void
1033duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
1128{ 1034{
1129 /* We assume both lists contain the same number of elements */ 1035 unsigned long pfn;
1130 while (src) { 1036
1131 dst->orig_address = src->orig_address; 1037 memory_bm_position_reset(src);
1132 dst = dst->next; 1038 pfn = memory_bm_next_pfn(src);
1133 src = src->next; 1039 while (pfn != BM_END_OF_MAP) {
1040 memory_bm_set_bit(dst, pfn);
1041 pfn = memory_bm_next_pfn(src);
1134 } 1042 }
1135} 1043}
1136 1044
1137static int check_header(struct swsusp_info *info) 1045static inline int check_header(struct swsusp_info *info)
1138{ 1046{
1139 char *reason = NULL; 1047 char *reason = NULL;
1140 1048
@@ -1161,19 +1069,14 @@ static int check_header(struct swsusp_info *info)
1161 * load header - check the image header and copy data from it 1069 * load header - check the image header and copy data from it
1162 */ 1070 */
1163 1071
1164static int load_header(struct snapshot_handle *handle, 1072static int
1165 struct swsusp_info *info) 1073load_header(struct swsusp_info *info)
1166{ 1074{
1167 int error; 1075 int error;
1168 struct pbe *pblist;
1169 1076
1077 restore_pblist = NULL;
1170 error = check_header(info); 1078 error = check_header(info);
1171 if (!error) { 1079 if (!error) {
1172 pblist = alloc_pagedir(info->image_pages, GFP_ATOMIC, PG_ANY);
1173 if (!pblist)
1174 return -ENOMEM;
1175 restore_pblist = pblist;
1176 handle->pbe = pblist;
1177 nr_copy_pages = info->image_pages; 1080 nr_copy_pages = info->image_pages;
1178 nr_meta_pages = info->pages - info->image_pages - 1; 1081 nr_meta_pages = info->pages - info->image_pages - 1;
1179 } 1082 }
@@ -1181,108 +1084,137 @@ static int load_header(struct snapshot_handle *handle,
1181} 1084}
1182 1085
1183/** 1086/**
1184 * unpack_orig_addresses - copy the elements of @buf[] (1 page) to 1087 * unpack_orig_pfns - for each element of @buf[] (1 page at a time) set
1185 * the PBEs in the list starting at @pbe 1088 * the corresponding bit in the memory bitmap @bm
1186 */ 1089 */
1187 1090
1188static inline struct pbe *unpack_orig_addresses(unsigned long *buf, 1091static inline void
1189 struct pbe *pbe) 1092unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
1190{ 1093{
1191 int j; 1094 int j;
1192 1095
1193 for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) { 1096 for (j = 0; j < PAGE_SIZE / sizeof(long); j++) {
1194 pbe->orig_address = buf[j]; 1097 if (unlikely(buf[j] == BM_END_OF_MAP))
1195 pbe = pbe->next; 1098 break;
1099
1100 memory_bm_set_bit(bm, buf[j]);
1196 } 1101 }
1197 return pbe;
1198} 1102}
1199 1103
1200/** 1104/**
1201 * prepare_image - use metadata contained in the PBE list 1105 * prepare_image - use the memory bitmap @bm to mark the pages that will
1202 * pointed to by restore_pblist to mark the pages that will 1106 * be overwritten in the process of restoring the system memory state
1203 * be overwritten in the process of restoring the system 1107 * from the suspend image ("unsafe" pages) and allocate memory for the
1204 * memory state from the image ("unsafe" pages) and allocate 1108 * image.
1205 * memory for the image
1206 * 1109 *
1207 * The idea is to allocate the PBE list first and then 1110 * The idea is to allocate a new memory bitmap first and then allocate
1208 * allocate as many pages as it's needed for the image data, 1111 * as many pages as needed for the image data, but not to assign these
1209 * but not to assign these pages to the PBEs initially. 1112 * pages to specific tasks initially. Instead, we just mark them as
1210 * Instead, we just mark them as allocated and create a list 1113 * allocated and create a list of "safe" pages that will be used later.
1211 * of "safe" which will be used later
1212 */ 1114 */
1213 1115
1214static struct linked_page *safe_pages; 1116#define PBES_PER_LINKED_PAGE (LINKED_PAGE_DATA_SIZE / sizeof(struct pbe))
1117
1118static struct linked_page *safe_pages_list;
1215 1119
1216static int prepare_image(struct snapshot_handle *handle) 1120static int
1121prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
1217{ 1122{
1218 int error = 0; 1123 unsigned int nr_pages;
1219 unsigned int nr_pages = nr_copy_pages; 1124 struct linked_page *sp_list, *lp;
1220 struct pbe *p, *pblist = NULL; 1125 int error;
1221 1126
1222 p = restore_pblist; 1127 error = mark_unsafe_pages(bm);
1223 error = mark_unsafe_pages(p); 1128 if (error)
1224 if (!error) { 1129 goto Free;
1225 pblist = alloc_pagedir(nr_pages, GFP_ATOMIC, PG_SAFE); 1130
1226 if (pblist) 1131 error = memory_bm_create(new_bm, GFP_ATOMIC, PG_SAFE);
1227 copy_page_backup_list(pblist, p); 1132 if (error)
1228 free_pagedir(p, PG_UNSAFE_KEEP); 1133 goto Free;
1229 if (!pblist) 1134
1135 duplicate_memory_bitmap(new_bm, bm);
1136 memory_bm_free(bm, PG_UNSAFE_KEEP);
1137 /* Reserve some safe pages for potential later use.
1138 *
1139 * NOTE: This way we make sure there will be enough safe pages for the
1140 * chain_alloc() in get_buffer(). It is a bit wasteful, but
1141 * nr_copy_pages cannot be greater than 50% of the memory anyway.
1142 */
1143 sp_list = NULL;
1144 /* nr_copy_pages cannot be lesser than allocated_unsafe_pages */
1145 nr_pages = nr_copy_pages - allocated_unsafe_pages;
1146 nr_pages = DIV_ROUND_UP(nr_pages, PBES_PER_LINKED_PAGE);
1147 while (nr_pages > 0) {
1148 lp = alloc_image_page(GFP_ATOMIC, PG_SAFE);
1149 if (!lp) {
1230 error = -ENOMEM; 1150 error = -ENOMEM;
1151 goto Free;
1152 }
1153 lp->next = sp_list;
1154 sp_list = lp;
1155 nr_pages--;
1231 } 1156 }
1232 safe_pages = NULL; 1157 /* Preallocate memory for the image */
1233 if (!error && nr_pages > unsafe_pages) { 1158 safe_pages_list = NULL;
1234 nr_pages -= unsafe_pages; 1159 nr_pages = nr_copy_pages - allocated_unsafe_pages;
1235 while (nr_pages--) { 1160 while (nr_pages > 0) {
1236 struct linked_page *ptr; 1161 lp = (struct linked_page *)get_zeroed_page(GFP_ATOMIC);
1237 1162 if (!lp) {
1238 ptr = (void *)get_zeroed_page(GFP_ATOMIC); 1163 error = -ENOMEM;
1239 if (!ptr) { 1164 goto Free;
1240 error = -ENOMEM; 1165 }
1241 break; 1166 if (!PageNosaveFree(virt_to_page(lp))) {
1242 } 1167 /* The page is "safe", add it to the list */
1243 if (!PageNosaveFree(virt_to_page(ptr))) { 1168 lp->next = safe_pages_list;
1244 /* The page is "safe", add it to the list */ 1169 safe_pages_list = lp;
1245 ptr->next = safe_pages;
1246 safe_pages = ptr;
1247 }
1248 /* Mark the page as allocated */
1249 SetPageNosave(virt_to_page(ptr));
1250 SetPageNosaveFree(virt_to_page(ptr));
1251 } 1170 }
1171 /* Mark the page as allocated */
1172 SetPageNosave(virt_to_page(lp));
1173 SetPageNosaveFree(virt_to_page(lp));
1174 nr_pages--;
1252 } 1175 }
1253 if (!error) { 1176 /* Free the reserved safe pages so that chain_alloc() can use them */
1254 restore_pblist = pblist; 1177 while (sp_list) {
1255 } else { 1178 lp = sp_list->next;
1256 handle->pbe = NULL; 1179 free_image_page(sp_list, PG_UNSAFE_CLEAR);
1257 swsusp_free(); 1180 sp_list = lp;
1258 } 1181 }
1182 return 0;
1183
1184Free:
1185 swsusp_free();
1259 return error; 1186 return error;
1260} 1187}
1261 1188
1262static void *get_buffer(struct snapshot_handle *handle) 1189/**
1190 * get_buffer - compute the address that snapshot_write_next() should
1191 * set for its caller to write to.
1192 */
1193
1194static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
1263{ 1195{
1264 struct pbe *pbe = handle->pbe, *last = handle->last_pbe; 1196 struct pbe *pbe;
1265 struct page *page = virt_to_page(pbe->orig_address); 1197 struct page *page = pfn_to_page(memory_bm_next_pfn(bm));
1266 1198
1267 if (PageNosave(page) && PageNosaveFree(page)) { 1199 if (PageNosave(page) && PageNosaveFree(page))
1268 /* 1200 /* We have allocated the "original" page frame and we can
1269 * We have allocated the "original" page frame and we can 1201 * use it directly to store the loaded page.
1270 * use it directly to store the read page
1271 */ 1202 */
1272 pbe->address = 0; 1203 return page_address(page);
1273 if (last && last->next) 1204
1274 last->next = NULL; 1205 /* The "original" page frame has not been allocated and we have to
1275 return (void *)pbe->orig_address; 1206 * use a "safe" page frame to store the loaded page.
1276 }
1277 /*
1278 * The "original" page frame has not been allocated and we have to
1279 * use a "safe" page frame to store the read page
1280 */ 1207 */
1281 pbe->address = (unsigned long)safe_pages; 1208 pbe = chain_alloc(ca, sizeof(struct pbe));
1282 safe_pages = safe_pages->next; 1209 if (!pbe) {
1283 if (last) 1210 swsusp_free();
1284 last->next = pbe; 1211 return NULL;
1285 handle->last_pbe = pbe; 1212 }
1213 pbe->orig_address = (unsigned long)page_address(page);
1214 pbe->address = (unsigned long)safe_pages_list;
1215 safe_pages_list = safe_pages_list->next;
1216 pbe->next = restore_pblist;
1217 restore_pblist = pbe;
1286 return (void *)pbe->address; 1218 return (void *)pbe->address;
1287} 1219}
1288 1220
@@ -1310,10 +1242,13 @@ static void *get_buffer(struct snapshot_handle *handle)
1310 1242
1311int snapshot_write_next(struct snapshot_handle *handle, size_t count) 1243int snapshot_write_next(struct snapshot_handle *handle, size_t count)
1312{ 1244{
1245 static struct chain_allocator ca;
1313 int error = 0; 1246 int error = 0;
1314 1247
1248 /* Check if we have already loaded the entire image */
1315 if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages) 1249 if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages)
1316 return 0; 1250 return 0;
1251
1317 if (!buffer) { 1252 if (!buffer) {
1318 /* This makes the buffer be freed by swsusp_free() */ 1253 /* This makes the buffer be freed by swsusp_free() */
1319 buffer = alloc_image_page(GFP_ATOMIC, PG_ANY); 1254 buffer = alloc_image_page(GFP_ATOMIC, PG_ANY);
@@ -1324,26 +1259,32 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count)
1324 handle->buffer = buffer; 1259 handle->buffer = buffer;
1325 handle->sync_read = 1; 1260 handle->sync_read = 1;
1326 if (handle->prev < handle->cur) { 1261 if (handle->prev < handle->cur) {
1327 if (!handle->prev) { 1262 if (handle->prev == 0) {
1328 error = load_header(handle, 1263 error = load_header(buffer);
1329 (struct swsusp_info *)buffer); 1264 if (error)
1265 return error;
1266
1267 error = memory_bm_create(&copy_bm, GFP_ATOMIC, PG_ANY);
1330 if (error) 1268 if (error)
1331 return error; 1269 return error;
1270
1332 } else if (handle->prev <= nr_meta_pages) { 1271 } else if (handle->prev <= nr_meta_pages) {
1333 handle->pbe = unpack_orig_addresses(buffer, 1272 unpack_orig_pfns(buffer, &copy_bm);
1334 handle->pbe); 1273 if (handle->prev == nr_meta_pages) {
1335 if (!handle->pbe) { 1274 error = prepare_image(&orig_bm, &copy_bm);
1336 error = prepare_image(handle);
1337 if (error) 1275 if (error)
1338 return error; 1276 return error;
1339 handle->pbe = restore_pblist; 1277
1340 handle->last_pbe = NULL; 1278 chain_init(&ca, GFP_ATOMIC, PG_SAFE);
1341 handle->buffer = get_buffer(handle); 1279 memory_bm_position_reset(&orig_bm);
1280 restore_pblist = NULL;
1281 handle->buffer = get_buffer(&orig_bm, &ca);
1342 handle->sync_read = 0; 1282 handle->sync_read = 0;
1283 if (!handle->buffer)
1284 return -ENOMEM;
1343 } 1285 }
1344 } else { 1286 } else {
1345 handle->pbe = handle->pbe->next; 1287 handle->buffer = get_buffer(&orig_bm, &ca);
1346 handle->buffer = get_buffer(handle);
1347 handle->sync_read = 0; 1288 handle->sync_read = 0;
1348 } 1289 }
1349 handle->prev = handle->cur; 1290 handle->prev = handle->cur;
@@ -1362,6 +1303,13 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count)
1362 1303
1363int snapshot_image_loaded(struct snapshot_handle *handle) 1304int snapshot_image_loaded(struct snapshot_handle *handle)
1364{ 1305{
1365 return !(!handle->pbe || handle->pbe->next || !nr_copy_pages || 1306 return !(!nr_copy_pages ||
1366 handle->cur <= nr_meta_pages + nr_copy_pages); 1307 handle->cur <= nr_meta_pages + nr_copy_pages);
1308}
1309
1310void snapshot_free_unused_memory(struct snapshot_handle *handle)
1311{
1312 /* Free only if we have loaded the image entirely */
1313 if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages)
1314 memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR);
1367} 1315}
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 8309d20b2563..9b2ee5344dee 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -331,8 +331,7 @@ static int enough_swap(unsigned int nr_pages)
331 unsigned int free_swap = count_swap_pages(root_swap, 1); 331 unsigned int free_swap = count_swap_pages(root_swap, 1);
332 332
333 pr_debug("swsusp: free swap pages: %u\n", free_swap); 333 pr_debug("swsusp: free swap pages: %u\n", free_swap);
334 return free_swap > (nr_pages + PAGES_FOR_IO + 334 return free_swap > nr_pages + PAGES_FOR_IO;
335 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
336} 335}
337 336
338/** 337/**
@@ -547,6 +546,7 @@ static int load_image(struct swap_map_handle *handle,
547 error = err2; 546 error = err2;
548 if (!error) { 547 if (!error) {
549 printk("\b\b\b\bdone\n"); 548 printk("\b\b\b\bdone\n");
549 snapshot_free_unused_memory(snapshot);
550 if (!snapshot_image_loaded(snapshot)) 550 if (!snapshot_image_loaded(snapshot))
551 error = -ENODATA; 551 error = -ENODATA;
552 } 552 }
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 0ef5e4ba39e5..2e4499f3e4d9 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -193,6 +193,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
193 error = -EPERM; 193 error = -EPERM;
194 break; 194 break;
195 } 195 }
196 snapshot_free_unused_memory(&data->handle);
196 down(&pm_sem); 197 down(&pm_sem);
197 pm_prepare_console(); 198 pm_prepare_console();
198 error = device_suspend(PMSG_FREEZE); 199 error = device_suspend(PMSG_FREEZE);