aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/snapshot.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-07-08 07:24:12 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2009-09-14 14:26:59 -0400
commitef4aede3f10d82adef1fb044b565ba5f08f851e0 (patch)
tree58566c694aa036e75df401979bd8a85ffa718f18 /kernel/power/snapshot.c
parent64a473cb74a88cb4991edf985d55a266e65292e1 (diff)
PM/Hibernate: Do not try to allocate too much memory too hard (rev. 2)
We want to avoid attempting to free too much memory too hard during hibernation, so estimate the minimum size of the image to use as the lower limit for preallocating memory. The approach here is based on the (experimental) observation that we can't free more page frames than the sum of: * global_page_state(NR_SLAB_RECLAIMABLE) * global_page_state(NR_ACTIVE_ANON) * global_page_state(NR_INACTIVE_ANON) * global_page_state(NR_ACTIVE_FILE) * global_page_state(NR_INACTIVE_FILE) minus * global_page_state(NR_FILE_MAPPED) Namely, if this number is subtracted from the number of saveable pages in the system, we get a good estimate of the minimum reasonable size of a hibernation image. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Wu Fengguang <fengguang.wu@intel.com>
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r--kernel/power/snapshot.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 2b1a7bc24c91..0a06b114dd33 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1204,6 +1204,36 @@ static void free_unnecessary_pages(void)
1204} 1204}
1205 1205
1206/** 1206/**
1207 * minimum_image_size - Estimate the minimum acceptable size of an image
1208 * @saveable: Number of saveable pages in the system.
1209 *
1210 * We want to avoid attempting to free too much memory too hard, so estimate the
1211 * minimum acceptable size of a hibernation image to use as the lower limit for
1212 * preallocating memory.
1213 *
1214 * We assume that the minimum image size should be proportional to
1215 *
1216 * [number of saveable pages] - [number of pages that can be freed in theory]
1217 *
1218 * where the second term is the sum of (1) reclaimable slab pages, (2) active
1219 * and (3) inactive anonymouns pages, (4) active and (5) inactive file pages,
1220 * minus mapped file pages.
1221 */
1222static unsigned long minimum_image_size(unsigned long saveable)
1223{
1224 unsigned long size;
1225
1226 size = global_page_state(NR_SLAB_RECLAIMABLE)
1227 + global_page_state(NR_ACTIVE_ANON)
1228 + global_page_state(NR_INACTIVE_ANON)
1229 + global_page_state(NR_ACTIVE_FILE)
1230 + global_page_state(NR_INACTIVE_FILE)
1231 - global_page_state(NR_FILE_MAPPED);
1232
1233 return saveable <= size ? 0 : saveable - size;
1234}
1235
1236/**
1207 * hibernate_preallocate_memory - Preallocate memory for hibernation image 1237 * hibernate_preallocate_memory - Preallocate memory for hibernation image
1208 * 1238 *
1209 * To create a hibernation image it is necessary to make a copy of every page 1239 * To create a hibernation image it is necessary to make a copy of every page
@@ -1220,8 +1250,8 @@ static void free_unnecessary_pages(void)
1220 * 1250 *
1221 * If image_size is set below the number following from the above formula, 1251 * If image_size is set below the number following from the above formula,
1222 * the preallocation of memory is continued until the total number of saveable 1252 * the preallocation of memory is continued until the total number of saveable
1223 * pages in the system is below the requested image size or it is impossible to 1253 * pages in the system is below the requested image size or the minimum
1224 * allocate more memory, whichever happens first. 1254 * acceptable image size returned by minimum_image_size(), whichever is greater.
1225 */ 1255 */
1226int hibernate_preallocate_memory(void) 1256int hibernate_preallocate_memory(void)
1227{ 1257{
@@ -1282,6 +1312,11 @@ int hibernate_preallocate_memory(void)
1282 goto out; 1312 goto out;
1283 } 1313 }
1284 1314
1315 /* Estimate the minimum size of the image. */
1316 pages = minimum_image_size(saveable);
1317 if (size < pages)
1318 size = min_t(unsigned long, pages, max_size);
1319
1285 /* 1320 /*
1286 * Let the memory management subsystem know that we're going to need a 1321 * Let the memory management subsystem know that we're going to need a
1287 * large number of page frames to allocate and make it free some memory. 1322 * large number of page frames to allocate and make it free some memory.
@@ -1294,8 +1329,8 @@ int hibernate_preallocate_memory(void)
1294 * The number of saveable pages in memory was too high, so apply some 1329 * The number of saveable pages in memory was too high, so apply some
1295 * pressure to decrease it. First, make room for the largest possible 1330 * pressure to decrease it. First, make room for the largest possible
1296 * image and fail if that doesn't work. Next, try to decrease the size 1331 * image and fail if that doesn't work. Next, try to decrease the size
1297 * of the image as much as indicated by image_size using allocations 1332 * of the image as much as indicated by 'size' using allocations from
1298 * from highmem and non-highmem zones separately. 1333 * highmem and non-highmem zones separately.
1299 */ 1334 */
1300 pages_highmem = preallocate_image_highmem(highmem / 2); 1335 pages_highmem = preallocate_image_highmem(highmem / 2);
1301 alloc = (count - max_size) - pages_highmem; 1336 alloc = (count - max_size) - pages_highmem;