Commit 84e1d836ef0759a152578a961894824bde89596f
Exists in
master
and in
20 other branches
Merge branch 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: PM / Hibernate: Avoid hitting OOM during preallocation of memory PM QoS: Correct pr_debug() misuse and improve parameter checks PM: Prevent waiting forever on asynchronous resume after failing suspend
Showing 3 changed files Side-by-side Diff
drivers/base/power/main.c
kernel/pm_qos_params.c
... | ... | @@ -389,10 +389,12 @@ |
389 | 389 | } else if (count == 11) { /* len('0x12345678/0') */ |
390 | 390 | if (copy_from_user(ascii_value, buf, 11)) |
391 | 391 | return -EFAULT; |
392 | + if (strlen(ascii_value) != 10) | |
393 | + return -EINVAL; | |
392 | 394 | x = sscanf(ascii_value, "%x", &value); |
393 | 395 | if (x != 1) |
394 | 396 | return -EINVAL; |
395 | - pr_debug(KERN_ERR "%s, %d, 0x%x\n", ascii_value, x, value); | |
397 | + pr_debug("%s, %d, 0x%x\n", ascii_value, x, value); | |
396 | 398 | } else |
397 | 399 | return -EINVAL; |
398 | 400 |
kernel/power/snapshot.c
... | ... | @@ -1121,9 +1121,19 @@ |
1121 | 1121 | return nr_alloc; |
1122 | 1122 | } |
1123 | 1123 | |
1124 | -static unsigned long preallocate_image_memory(unsigned long nr_pages) | |
1124 | +static unsigned long preallocate_image_memory(unsigned long nr_pages, | |
1125 | + unsigned long avail_normal) | |
1125 | 1126 | { |
1126 | - return preallocate_image_pages(nr_pages, GFP_IMAGE); | |
1127 | + unsigned long alloc; | |
1128 | + | |
1129 | + if (avail_normal <= alloc_normal) | |
1130 | + return 0; | |
1131 | + | |
1132 | + alloc = avail_normal - alloc_normal; | |
1133 | + if (nr_pages < alloc) | |
1134 | + alloc = nr_pages; | |
1135 | + | |
1136 | + return preallocate_image_pages(alloc, GFP_IMAGE); | |
1127 | 1137 | } |
1128 | 1138 | |
1129 | 1139 | #ifdef CONFIG_HIGHMEM |
1130 | 1140 | |
1131 | 1141 | |
1132 | 1142 | |
... | ... | @@ -1169,15 +1179,22 @@ |
1169 | 1179 | */ |
1170 | 1180 | static void free_unnecessary_pages(void) |
1171 | 1181 | { |
1172 | - unsigned long save_highmem, to_free_normal, to_free_highmem; | |
1182 | + unsigned long save, to_free_normal, to_free_highmem; | |
1173 | 1183 | |
1174 | - to_free_normal = alloc_normal - count_data_pages(); | |
1175 | - save_highmem = count_highmem_pages(); | |
1176 | - if (alloc_highmem > save_highmem) { | |
1177 | - to_free_highmem = alloc_highmem - save_highmem; | |
1184 | + save = count_data_pages(); | |
1185 | + if (alloc_normal >= save) { | |
1186 | + to_free_normal = alloc_normal - save; | |
1187 | + save = 0; | |
1178 | 1188 | } else { |
1189 | + to_free_normal = 0; | |
1190 | + save -= alloc_normal; | |
1191 | + } | |
1192 | + save += count_highmem_pages(); | |
1193 | + if (alloc_highmem >= save) { | |
1194 | + to_free_highmem = alloc_highmem - save; | |
1195 | + } else { | |
1179 | 1196 | to_free_highmem = 0; |
1180 | - to_free_normal -= save_highmem - alloc_highmem; | |
1197 | + to_free_normal -= save - alloc_highmem; | |
1181 | 1198 | } |
1182 | 1199 | |
1183 | 1200 | memory_bm_position_reset(©_bm); |
... | ... | @@ -1258,7 +1275,7 @@ |
1258 | 1275 | { |
1259 | 1276 | struct zone *zone; |
1260 | 1277 | unsigned long saveable, size, max_size, count, highmem, pages = 0; |
1261 | - unsigned long alloc, save_highmem, pages_highmem; | |
1278 | + unsigned long alloc, save_highmem, pages_highmem, avail_normal; | |
1262 | 1279 | struct timeval start, stop; |
1263 | 1280 | int error; |
1264 | 1281 | |
... | ... | @@ -1295,6 +1312,7 @@ |
1295 | 1312 | else |
1296 | 1313 | count += zone_page_state(zone, NR_FREE_PAGES); |
1297 | 1314 | } |
1315 | + avail_normal = count; | |
1298 | 1316 | count += highmem; |
1299 | 1317 | count -= totalreserve_pages; |
1300 | 1318 | |
1301 | 1319 | |
... | ... | @@ -1309,12 +1327,21 @@ |
1309 | 1327 | */ |
1310 | 1328 | if (size >= saveable) { |
1311 | 1329 | pages = preallocate_image_highmem(save_highmem); |
1312 | - pages += preallocate_image_memory(saveable - pages); | |
1330 | + pages += preallocate_image_memory(saveable - pages, avail_normal); | |
1313 | 1331 | goto out; |
1314 | 1332 | } |
1315 | 1333 | |
1316 | 1334 | /* Estimate the minimum size of the image. */ |
1317 | 1335 | pages = minimum_image_size(saveable); |
1336 | + /* | |
1337 | + * To avoid excessive pressure on the normal zone, leave room in it to | |
1338 | + * accommodate an image of the minimum size (unless it's already too | |
1339 | + * small, in which case don't preallocate pages from it at all). | |
1340 | + */ | |
1341 | + if (avail_normal > pages) | |
1342 | + avail_normal -= pages; | |
1343 | + else | |
1344 | + avail_normal = 0; | |
1318 | 1345 | if (size < pages) |
1319 | 1346 | size = min_t(unsigned long, pages, max_size); |
1320 | 1347 | |
... | ... | @@ -1335,16 +1362,34 @@ |
1335 | 1362 | */ |
1336 | 1363 | pages_highmem = preallocate_image_highmem(highmem / 2); |
1337 | 1364 | alloc = (count - max_size) - pages_highmem; |
1338 | - pages = preallocate_image_memory(alloc); | |
1339 | - if (pages < alloc) | |
1340 | - goto err_out; | |
1341 | - size = max_size - size; | |
1342 | - alloc = size; | |
1343 | - size = preallocate_highmem_fraction(size, highmem, count); | |
1344 | - pages_highmem += size; | |
1345 | - alloc -= size; | |
1346 | - pages += preallocate_image_memory(alloc); | |
1347 | - pages += pages_highmem; | |
1365 | + pages = preallocate_image_memory(alloc, avail_normal); | |
1366 | + if (pages < alloc) { | |
1367 | + /* We have exhausted non-highmem pages, try highmem. */ | |
1368 | + alloc -= pages; | |
1369 | + pages += pages_highmem; | |
1370 | + pages_highmem = preallocate_image_highmem(alloc); | |
1371 | + if (pages_highmem < alloc) | |
1372 | + goto err_out; | |
1373 | + pages += pages_highmem; | |
1374 | + /* | |
1375 | + * size is the desired number of saveable pages to leave in | |
1376 | + * memory, so try to preallocate (all memory - size) pages. | |
1377 | + */ | |
1378 | + alloc = (count - pages) - size; | |
1379 | + pages += preallocate_image_highmem(alloc); | |
1380 | + } else { | |
1381 | + /* | |
1382 | + * There are approximately max_size saveable pages at this point | |
1383 | + * and we want to reduce this number down to size. | |
1384 | + */ | |
1385 | + alloc = max_size - size; | |
1386 | + size = preallocate_highmem_fraction(alloc, highmem, count); | |
1387 | + pages_highmem += size; | |
1388 | + alloc -= size; | |
1389 | + size = preallocate_image_memory(alloc, avail_normal); | |
1390 | + pages_highmem += preallocate_image_highmem(alloc - size); | |
1391 | + pages += pages_highmem + size; | |
1392 | + } | |
1348 | 1393 | |
1349 | 1394 | /* |
1350 | 1395 | * We only need as many page frames for the image as there are saveable |