diff options
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/hibernate.c | 15 | ||||
-rw-r--r-- | kernel/power/power.h | 2 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 202 |
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 | ||
75 | extern int create_basic_memory_bitmaps(void); | 75 | extern int create_basic_memory_bitmaps(void); |
76 | extern void free_basic_memory_bitmaps(void); | 76 | extern void free_basic_memory_bitmaps(void); |
77 | extern int swsusp_shrink_memory(void); | 77 | extern 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) | |||
1033 | static unsigned int nr_copy_pages; | 1033 | static 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 */ |
1035 | static unsigned int nr_meta_pages; | 1035 | static unsigned int nr_meta_pages; |
1036 | /* | ||
1037 | * Numbers of normal and highmem page frames allocated for hibernation image | ||
1038 | * before suspending devices. | ||
1039 | */ | ||
1040 | unsigned int alloc_normal, alloc_highmem; | ||
1041 | /* | ||
1042 | * Memory bitmap used for marking saveable pages (during hibernation) or | ||
1043 | * hibernation image pages (during restore) | ||
1044 | */ | ||
1045 | static 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 | */ | ||
1054 | static 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(©_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 | */ | ||
1169 | static 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(©_bm); | ||
1183 | |||
1184 | while (to_free_normal > 0 && to_free_highmem > 0) { | ||
1185 | unsigned long pfn = memory_bm_next_pfn(©_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(©_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 | */ |
1157 | int swsusp_shrink_memory(void) | 1226 | int 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(©_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 | ||
1254 | static unsigned int count_pages_for_highmem(unsigned int nr_highmem) | 1339 | static 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; } | |||
1275 | static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem) | 1360 | static 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 | ||
1311 | static inline unsigned int | 1394 | static inline unsigned int |
1312 | alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem) | 1395 | alloc_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) | |||
1329 | static inline int get_highmem_buffer(int safe_needed) { return 0; } | 1412 | static inline int get_highmem_buffer(int safe_needed) { return 0; } |
1330 | 1413 | ||
1331 | static inline unsigned int | 1414 | static inline unsigned int |
1332 | alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int n) { return 0; } | 1415 | alloc_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 | |||
1348 | swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, | 1431 | swsusp_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 | */ | ||
1386 | static 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 | */ | ||
1394 | static struct memory_bitmap copy_bm; | ||
1395 | |||
1396 | asmlinkage int swsusp_save(void) | 1464 | asmlinkage int swsusp_save(void) |
1397 | { | 1465 | { |
1398 | unsigned int nr_pages, nr_highmem; | 1466 | unsigned int nr_pages, nr_highmem; |