aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-07-08 07:24:05 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2009-09-14 14:26:58 -0400
commit64a473cb74a88cb4991edf985d55a266e65292e1 (patch)
tree173402070f904951c9ec16a55e3f96e75289f14c /kernel
parent4bb334353ebd821bc8eeabeb019eaac33c7307df (diff)
PM/Hibernate: Do not release preallocated memory unnecessarily (rev. 2)
Since the hibernation code is now going to use allocations of memory to make enough room for the image, it can also use the page frames allocated at this stage as image page frames. The low-level hibernation code needs to be rearranged for this purpose, but it allows us to avoid freeing a great number of pages and allocating these same pages once again later, so it generally is worth doing. [rev. 2: Take highmem into account correctly.] Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/hibernate.c15
-rw-r--r--kernel/power/power.h2
-rw-r--r--kernel/power/snapshot.c202
3 files changed, 147 insertions, 72 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index ec8202512b05..04b3a83d686f 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -298,8 +298,8 @@ int hibernation_snapshot(int platform_mode)
298 if (error) 298 if (error)
299 return error; 299 return error;
300 300
301 /* Free memory before shutting down devices. */ 301 /* Preallocate image memory before shutting down devices. */
302 error = swsusp_shrink_memory(); 302 error = hibernate_preallocate_memory();
303 if (error) 303 if (error)
304 goto Close; 304 goto Close;
305 305
@@ -315,6 +315,10 @@ int hibernation_snapshot(int platform_mode)
315 /* Control returns here after successful restore */ 315 /* Control returns here after successful restore */
316 316
317 Resume_devices: 317 Resume_devices:
318 /* We may need to release the preallocated image pages here. */
319 if (error || !in_suspend)
320 swsusp_free();
321
318 dpm_resume_end(in_suspend ? 322 dpm_resume_end(in_suspend ?
319 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 323 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
320 resume_console(); 324 resume_console();
@@ -578,7 +582,10 @@ int hibernate(void)
578 goto Thaw; 582 goto Thaw;
579 583
580 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); 584 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
581 if (in_suspend && !error) { 585 if (error)
586 goto Thaw;
587
588 if (in_suspend) {
582 unsigned int flags = 0; 589 unsigned int flags = 0;
583 590
584 if (hibernation_mode == HIBERNATION_PLATFORM) 591 if (hibernation_mode == HIBERNATION_PLATFORM)
@@ -590,8 +597,8 @@ int hibernate(void)
590 power_down(); 597 power_down();
591 } else { 598 } else {
592 pr_debug("PM: Image restored successfully.\n"); 599 pr_debug("PM: Image restored successfully.\n");
593 swsusp_free();
594 } 600 }
601
595 Thaw: 602 Thaw:
596 thaw_processes(); 603 thaw_processes();
597 Finish: 604 Finish:
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 26d5a26f82e3..46c5a26630a3 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -74,7 +74,7 @@ extern asmlinkage int swsusp_arch_resume(void);
74 74
75extern int create_basic_memory_bitmaps(void); 75extern int create_basic_memory_bitmaps(void);
76extern void free_basic_memory_bitmaps(void); 76extern void free_basic_memory_bitmaps(void);
77extern int swsusp_shrink_memory(void); 77extern int hibernate_preallocate_memory(void);
78 78
79/** 79/**
80 * Auxiliary structure used for reading the snapshot image data and 80 * Auxiliary structure used for reading the snapshot image data and
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a3a175fa0a46..2b1a7bc24c91 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1033,6 +1033,25 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
1033static unsigned int nr_copy_pages; 1033static unsigned int nr_copy_pages;
1034/* Number of pages needed for saving the original pfns of the image pages */ 1034/* Number of pages needed for saving the original pfns of the image pages */
1035static unsigned int nr_meta_pages; 1035static unsigned int nr_meta_pages;
1036/*
1037 * Numbers of normal and highmem page frames allocated for hibernation image
1038 * before suspending devices.
1039 */
1040unsigned int alloc_normal, alloc_highmem;
1041/*
1042 * Memory bitmap used for marking saveable pages (during hibernation) or
1043 * hibernation image pages (during restore)
1044 */
1045static struct memory_bitmap orig_bm;
1046/*
1047 * Memory bitmap used during hibernation for marking allocated page frames that
1048 * will contain copies of saveable pages. During restore it is initially used
1049 * for marking hibernation image pages, but then the set bits from it are
1050 * duplicated in @orig_bm and it is released. On highmem systems it is next
1051 * used for marking "safe" highmem pages, but it has to be reinitialized for
1052 * this purpose.
1053 */
1054static struct memory_bitmap copy_bm;
1036 1055
1037/** 1056/**
1038 * swsusp_free - free pages allocated for the suspend. 1057 * swsusp_free - free pages allocated for the suspend.
@@ -1064,6 +1083,8 @@ void swsusp_free(void)
1064 nr_meta_pages = 0; 1083 nr_meta_pages = 0;
1065 restore_pblist = NULL; 1084 restore_pblist = NULL;
1066 buffer = NULL; 1085 buffer = NULL;
1086 alloc_normal = 0;
1087 alloc_highmem = 0;
1067} 1088}
1068 1089
1069/* Helper functions used for the shrinking of memory. */ 1090/* Helper functions used for the shrinking of memory. */
@@ -1082,8 +1103,16 @@ static unsigned long preallocate_image_pages(unsigned long nr_pages, gfp_t mask)
1082 unsigned long nr_alloc = 0; 1103 unsigned long nr_alloc = 0;
1083 1104
1084 while (nr_pages > 0) { 1105 while (nr_pages > 0) {
1085 if (!alloc_image_page(mask)) 1106 struct page *page;
1107
1108 page = alloc_image_page(mask);
1109 if (!page)
1086 break; 1110 break;
1111 memory_bm_set_bit(&copy_bm, page_to_pfn(page));
1112 if (PageHighMem(page))
1113 alloc_highmem++;
1114 else
1115 alloc_normal++;
1087 nr_pages--; 1116 nr_pages--;
1088 nr_alloc++; 1117 nr_alloc++;
1089 } 1118 }
@@ -1135,7 +1164,47 @@ static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages,
1135#endif /* CONFIG_HIGHMEM */ 1164#endif /* CONFIG_HIGHMEM */
1136 1165
1137/** 1166/**
1138 * swsusp_shrink_memory - Make the kernel release as much memory as needed 1167 * free_unnecessary_pages - Release preallocated pages not needed for the image
1168 */
1169static void free_unnecessary_pages(void)
1170{
1171 unsigned long save_highmem, to_free_normal, to_free_highmem;
1172
1173 to_free_normal = alloc_normal - count_data_pages();
1174 save_highmem = count_highmem_pages();
1175 if (alloc_highmem > save_highmem) {
1176 to_free_highmem = alloc_highmem - save_highmem;
1177 } else {
1178 to_free_highmem = 0;
1179 to_free_normal -= save_highmem - alloc_highmem;
1180 }
1181
1182 memory_bm_position_reset(&copy_bm);
1183
1184 while (to_free_normal > 0 && to_free_highmem > 0) {
1185 unsigned long pfn = memory_bm_next_pfn(&copy_bm);
1186 struct page *page = pfn_to_page(pfn);
1187
1188 if (PageHighMem(page)) {
1189 if (!to_free_highmem)
1190 continue;
1191 to_free_highmem--;
1192 alloc_highmem--;
1193 } else {
1194 if (!to_free_normal)
1195 continue;
1196 to_free_normal--;
1197 alloc_normal--;
1198 }
1199 memory_bm_clear_bit(&copy_bm, pfn);
1200 swsusp_unset_page_forbidden(page);
1201 swsusp_unset_page_free(page);
1202 __free_page(page);
1203 }
1204}
1205
1206/**
1207 * hibernate_preallocate_memory - Preallocate memory for hibernation image
1139 * 1208 *
1140 * To create a hibernation image it is necessary to make a copy of every page 1209 * To create a hibernation image it is necessary to make a copy of every page
1141 * frame in use. We also need a number of page frames to be free during 1210 * frame in use. We also need a number of page frames to be free during
@@ -1154,19 +1223,30 @@ static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages,
1154 * pages in the system is below the requested image size or it is impossible to 1223 * pages in the system is below the requested image size or it is impossible to
1155 * allocate more memory, whichever happens first. 1224 * allocate more memory, whichever happens first.
1156 */ 1225 */
1157int swsusp_shrink_memory(void) 1226int hibernate_preallocate_memory(void)
1158{ 1227{
1159 struct zone *zone; 1228 struct zone *zone;
1160 unsigned long saveable, size, max_size, count, highmem, pages = 0; 1229 unsigned long saveable, size, max_size, count, highmem, pages = 0;
1161 unsigned long alloc, pages_highmem; 1230 unsigned long alloc, save_highmem, pages_highmem;
1162 struct timeval start, stop; 1231 struct timeval start, stop;
1163 int error = 0; 1232 int error;
1164 1233
1165 printk(KERN_INFO "PM: Shrinking memory... "); 1234 printk(KERN_INFO "PM: Preallocating image memory... ");
1166 do_gettimeofday(&start); 1235 do_gettimeofday(&start);
1167 1236
1237 error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
1238 if (error)
1239 goto err_out;
1240
1241 error = memory_bm_create(&copy_bm, GFP_IMAGE, PG_ANY);
1242 if (error)
1243 goto err_out;
1244
1245 alloc_normal = 0;
1246 alloc_highmem = 0;
1247
1168 /* Count the number of saveable data pages. */ 1248 /* Count the number of saveable data pages. */
1169 highmem = count_highmem_pages(); 1249 save_highmem = count_highmem_pages();
1170 saveable = count_data_pages(); 1250 saveable = count_data_pages();
1171 1251
1172 /* 1252 /*
@@ -1174,7 +1254,8 @@ int swsusp_shrink_memory(void)
1174 * number of pages needed for image metadata (size). 1254 * number of pages needed for image metadata (size).
1175 */ 1255 */
1176 count = saveable; 1256 count = saveable;
1177 saveable += highmem; 1257 saveable += save_highmem;
1258 highmem = save_highmem;
1178 size = 0; 1259 size = 0;
1179 for_each_populated_zone(zone) { 1260 for_each_populated_zone(zone) {
1180 size += snapshot_additional_pages(zone); 1261 size += snapshot_additional_pages(zone);
@@ -1193,10 +1274,13 @@ int swsusp_shrink_memory(void)
1193 size = max_size; 1274 size = max_size;
1194 /* 1275 /*
1195 * If the maximum is not less than the current number of saveable pages 1276 * If the maximum is not less than the current number of saveable pages
1196 * in memory, we don't need to do anything more. 1277 * in memory, allocate page frames for the image and we're done.
1197 */ 1278 */
1198 if (size >= saveable) 1279 if (size >= saveable) {
1280 pages = preallocate_image_highmem(save_highmem);
1281 pages += preallocate_image_memory(saveable - pages);
1199 goto out; 1282 goto out;
1283 }
1200 1284
1201 /* 1285 /*
1202 * Let the memory management subsystem know that we're going to need a 1286 * Let the memory management subsystem know that we're going to need a
@@ -1216,10 +1300,8 @@ int swsusp_shrink_memory(void)
1216 pages_highmem = preallocate_image_highmem(highmem / 2); 1300 pages_highmem = preallocate_image_highmem(highmem / 2);
1217 alloc = (count - max_size) - pages_highmem; 1301 alloc = (count - max_size) - pages_highmem;
1218 pages = preallocate_image_memory(alloc); 1302 pages = preallocate_image_memory(alloc);
1219 if (pages < alloc) { 1303 if (pages < alloc)
1220 error = -ENOMEM; 1304 goto err_out;
1221 goto free_out;
1222 }
1223 size = max_size - size; 1305 size = max_size - size;
1224 alloc = size; 1306 alloc = size;
1225 size = preallocate_highmem_fraction(size, highmem, count); 1307 size = preallocate_highmem_fraction(size, highmem, count);
@@ -1228,21 +1310,24 @@ int swsusp_shrink_memory(void)
1228 pages += preallocate_image_memory(alloc); 1310 pages += preallocate_image_memory(alloc);
1229 pages += pages_highmem; 1311 pages += pages_highmem;
1230 1312
1231 free_out: 1313 /*
1232 /* Release all of the preallocated page frames. */ 1314 * We only need as many page frames for the image as there are saveable
1233 swsusp_free(); 1315 * pages in memory, but we have allocated more. Release the excessive
1234 1316 * ones now.
1235 if (error) { 1317 */
1236 printk(KERN_CONT "\n"); 1318 free_unnecessary_pages();
1237 return error;
1238 }
1239 1319
1240 out: 1320 out:
1241 do_gettimeofday(&stop); 1321 do_gettimeofday(&stop);
1242 printk(KERN_CONT "done (preallocated %lu free pages)\n", pages); 1322 printk(KERN_CONT "done (allocated %lu pages)\n", pages);
1243 swsusp_show_speed(&start, &stop, pages, "Freed"); 1323 swsusp_show_speed(&start, &stop, pages, "Allocated");
1244 1324
1245 return 0; 1325 return 0;
1326
1327 err_out:
1328 printk(KERN_CONT "\n");
1329 swsusp_free();
1330 return -ENOMEM;
1246} 1331}
1247 1332
1248#ifdef CONFIG_HIGHMEM 1333#ifdef CONFIG_HIGHMEM
@@ -1253,7 +1338,7 @@ int swsusp_shrink_memory(void)
1253 1338
1254static unsigned int count_pages_for_highmem(unsigned int nr_highmem) 1339static unsigned int count_pages_for_highmem(unsigned int nr_highmem)
1255{ 1340{
1256 unsigned int free_highmem = count_free_highmem_pages(); 1341 unsigned int free_highmem = count_free_highmem_pages() + alloc_highmem;
1257 1342
1258 if (free_highmem >= nr_highmem) 1343 if (free_highmem >= nr_highmem)
1259 nr_highmem = 0; 1344 nr_highmem = 0;
@@ -1275,19 +1360,17 @@ count_pages_for_highmem(unsigned int nr_highmem) { return 0; }
1275static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem) 1360static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
1276{ 1361{
1277 struct zone *zone; 1362 struct zone *zone;
1278 unsigned int free = 0, meta = 0; 1363 unsigned int free = alloc_normal;
1279 1364
1280 for_each_zone(zone) { 1365 for_each_zone(zone)
1281 meta += snapshot_additional_pages(zone);
1282 if (!is_highmem(zone)) 1366 if (!is_highmem(zone))
1283 free += zone_page_state(zone, NR_FREE_PAGES); 1367 free += zone_page_state(zone, NR_FREE_PAGES);
1284 }
1285 1368
1286 nr_pages += count_pages_for_highmem(nr_highmem); 1369 nr_pages += count_pages_for_highmem(nr_highmem);
1287 pr_debug("PM: Normal pages needed: %u + %u + %u, available pages: %u\n", 1370 pr_debug("PM: Normal pages needed: %u + %u, available pages: %u\n",
1288 nr_pages, PAGES_FOR_IO, meta, free); 1371 nr_pages, PAGES_FOR_IO, free);
1289 1372
1290 return free > nr_pages + PAGES_FOR_IO + meta; 1373 return free > nr_pages + PAGES_FOR_IO;
1291} 1374}
1292 1375
1293#ifdef CONFIG_HIGHMEM 1376#ifdef CONFIG_HIGHMEM
@@ -1309,7 +1392,7 @@ static inline int get_highmem_buffer(int safe_needed)
1309 */ 1392 */
1310 1393
1311static inline unsigned int 1394static inline unsigned int
1312alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem) 1395alloc_highmem_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
1313{ 1396{
1314 unsigned int to_alloc = count_free_highmem_pages(); 1397 unsigned int to_alloc = count_free_highmem_pages();
1315 1398
@@ -1329,7 +1412,7 @@ alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
1329static inline int get_highmem_buffer(int safe_needed) { return 0; } 1412static inline int get_highmem_buffer(int safe_needed) { return 0; }
1330 1413
1331static inline unsigned int 1414static inline unsigned int
1332alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int n) { return 0; } 1415alloc_highmem_pages(struct memory_bitmap *bm, unsigned int n) { return 0; }
1333#endif /* CONFIG_HIGHMEM */ 1416#endif /* CONFIG_HIGHMEM */
1334 1417
1335/** 1418/**
@@ -1348,51 +1431,36 @@ static int
1348swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, 1431swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm,
1349 unsigned int nr_pages, unsigned int nr_highmem) 1432 unsigned int nr_pages, unsigned int nr_highmem)
1350{ 1433{
1351 int error; 1434 int error = 0;
1352
1353 error = memory_bm_create(orig_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
1354 if (error)
1355 goto Free;
1356
1357 error = memory_bm_create(copy_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
1358 if (error)
1359 goto Free;
1360 1435
1361 if (nr_highmem > 0) { 1436 if (nr_highmem > 0) {
1362 error = get_highmem_buffer(PG_ANY); 1437 error = get_highmem_buffer(PG_ANY);
1363 if (error) 1438 if (error)
1364 goto Free; 1439 goto err_out;
1365 1440 if (nr_highmem > alloc_highmem) {
1366 nr_pages += alloc_highmem_image_pages(copy_bm, nr_highmem); 1441 nr_highmem -= alloc_highmem;
1442 nr_pages += alloc_highmem_pages(copy_bm, nr_highmem);
1443 }
1367 } 1444 }
1368 while (nr_pages-- > 0) { 1445 if (nr_pages > alloc_normal) {
1369 struct page *page = alloc_image_page(GFP_ATOMIC | __GFP_COLD); 1446 nr_pages -= alloc_normal;
1370 1447 while (nr_pages-- > 0) {
1371 if (!page) 1448 struct page *page;
1372 goto Free;
1373 1449
1374 memory_bm_set_bit(copy_bm, page_to_pfn(page)); 1450 page = alloc_image_page(GFP_ATOMIC | __GFP_COLD);
1451 if (!page)
1452 goto err_out;
1453 memory_bm_set_bit(copy_bm, page_to_pfn(page));
1454 }
1375 } 1455 }
1456
1376 return 0; 1457 return 0;
1377 1458
1378 Free: 1459 err_out:
1379 swsusp_free(); 1460 swsusp_free();
1380 return -ENOMEM; 1461 return error;
1381} 1462}
1382 1463
1383/* Memory bitmap used for marking saveable pages (during suspend) or the
1384 * suspend image pages (during resume)
1385 */
1386static struct memory_bitmap orig_bm;
1387/* Memory bitmap used on suspend for marking allocated pages that will contain
1388 * the copies of saveable pages. During resume it is initially used for
1389 * marking the suspend image pages, but then its set bits are duplicated in
1390 * @orig_bm and it is released. Next, on systems with high memory, it may be
1391 * used for marking "safe" highmem pages, but it has to be reinitialized for
1392 * this purpose.
1393 */
1394static struct memory_bitmap copy_bm;
1395
1396asmlinkage int swsusp_save(void) 1464asmlinkage int swsusp_save(void)
1397{ 1465{
1398 unsigned int nr_pages, nr_highmem; 1466 unsigned int nr_pages, nr_highmem;