aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/swsusp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/swsusp.c')
-rw-r--r--kernel/power/swsusp.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index c4016cbbd3e0..f0ee4e7780d6 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -62,16 +62,6 @@ unsigned long image_size = 500 * 1024 * 1024;
62 62
63int in_suspend __nosavedata = 0; 63int in_suspend __nosavedata = 0;
64 64
65#ifdef CONFIG_HIGHMEM
66unsigned int count_highmem_pages(void);
67int save_highmem(void);
68int restore_highmem(void);
69#else
70static int save_highmem(void) { return 0; }
71static int restore_highmem(void) { return 0; }
72static unsigned int count_highmem_pages(void) { return 0; }
73#endif
74
75/** 65/**
76 * The following functions are used for tracing the allocated 66 * The following functions are used for tracing the allocated
77 * swap pages, so that they can be freed in case of an error. 67 * swap pages, so that they can be freed in case of an error.
@@ -175,6 +165,12 @@ void free_all_swap_pages(int swap, struct bitmap_page *bitmap)
175 */ 165 */
176 166
177#define SHRINK_BITE 10000 167#define SHRINK_BITE 10000
168static inline unsigned long __shrink_memory(long tmp)
169{
170 if (tmp > SHRINK_BITE)
171 tmp = SHRINK_BITE;
172 return shrink_all_memory(tmp);
173}
178 174
179int swsusp_shrink_memory(void) 175int swsusp_shrink_memory(void)
180{ 176{
@@ -186,21 +182,23 @@ int swsusp_shrink_memory(void)
186 182
187 printk("Shrinking memory... "); 183 printk("Shrinking memory... ");
188 do { 184 do {
189 size = 2 * count_highmem_pages(); 185 size = 2 * count_special_pages();
190 size += size / 50 + count_data_pages(); 186 size += size / 50 + count_data_pages();
191 size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE + 187 size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE +
192 PAGES_FOR_IO; 188 PAGES_FOR_IO;
193 tmp = size; 189 tmp = size;
194 for_each_zone (zone) 190 for_each_zone (zone)
195 if (!is_highmem(zone)) 191 if (!is_highmem(zone) && populated_zone(zone)) {
196 tmp -= zone->free_pages; 192 tmp -= zone->free_pages;
193 tmp += zone->lowmem_reserve[ZONE_NORMAL];
194 }
197 if (tmp > 0) { 195 if (tmp > 0) {
198 tmp = shrink_all_memory(SHRINK_BITE); 196 tmp = __shrink_memory(tmp);
199 if (!tmp) 197 if (!tmp)
200 return -ENOMEM; 198 return -ENOMEM;
201 pages += tmp; 199 pages += tmp;
202 } else if (size > image_size / PAGE_SIZE) { 200 } else if (size > image_size / PAGE_SIZE) {
203 tmp = shrink_all_memory(SHRINK_BITE); 201 tmp = __shrink_memory(size - (image_size / PAGE_SIZE));
204 pages += tmp; 202 pages += tmp;
205 } 203 }
206 printk("\b%c", p[i++%4]); 204 printk("\b%c", p[i++%4]);
@@ -228,7 +226,7 @@ int swsusp_suspend(void)
228 goto Enable_irqs; 226 goto Enable_irqs;
229 } 227 }
230 228
231 if ((error = save_highmem())) { 229 if ((error = save_special_mem())) {
232 printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); 230 printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
233 goto Restore_highmem; 231 goto Restore_highmem;
234 } 232 }
@@ -239,7 +237,7 @@ int swsusp_suspend(void)
239 /* Restore control flow magically appears here */ 237 /* Restore control flow magically appears here */
240 restore_processor_state(); 238 restore_processor_state();
241Restore_highmem: 239Restore_highmem:
242 restore_highmem(); 240 restore_special_mem();
243 device_power_up(); 241 device_power_up();
244Enable_irqs: 242Enable_irqs:
245 local_irq_enable(); 243 local_irq_enable();
@@ -265,7 +263,7 @@ int swsusp_resume(void)
265 */ 263 */
266 swsusp_free(); 264 swsusp_free();
267 restore_processor_state(); 265 restore_processor_state();
268 restore_highmem(); 266 restore_special_mem();
269 touch_softlockup_watchdog(); 267 touch_softlockup_watchdog();
270 device_power_up(); 268 device_power_up();
271 local_irq_enable(); 269 local_irq_enable();