diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/oom_kill.c | 12 | ||||
-rw-r--r-- | mm/page_alloc.c | 7 | ||||
-rw-r--r-- | mm/slab.c | 4 | ||||
-rw-r--r-- | mm/swapfile.c | 8 | ||||
-rw-r--r-- | mm/vmscan.c | 33 |
5 files changed, 38 insertions, 26 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 6969cfb33901..b278b8d60eee 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -61,12 +61,6 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * swapoff can easily use up all memory, so kill those first. | ||
65 | */ | ||
66 | if (p->flags & PF_SWAPOFF) | ||
67 | return ULONG_MAX; | ||
68 | |||
69 | /* | ||
70 | * The memory size of the process is the basis for the badness. | 64 | * The memory size of the process is the basis for the badness. |
71 | */ | 65 | */ |
72 | points = mm->total_vm; | 66 | points = mm->total_vm; |
@@ -77,6 +71,12 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
77 | task_unlock(p); | 71 | task_unlock(p); |
78 | 72 | ||
79 | /* | 73 | /* |
74 | * swapoff can easily use up all memory, so kill those first. | ||
75 | */ | ||
76 | if (p->flags & PF_SWAPOFF) | ||
77 | return ULONG_MAX; | ||
78 | |||
79 | /* | ||
80 | * Processes which fork a lot of child processes are likely | 80 | * Processes which fork a lot of child processes are likely |
81 | * a good choice. We add half the vmsize of the children if they | 81 | * a good choice. We add half the vmsize of the children if they |
82 | * have an own mm. This prevents forking servers to flood the | 82 | * have an own mm. This prevents forking servers to flood the |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8c1a116875bc..a49f96b7ea43 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -711,6 +711,9 @@ static void __drain_pages(unsigned int cpu) | |||
711 | for_each_zone(zone) { | 711 | for_each_zone(zone) { |
712 | struct per_cpu_pageset *pset; | 712 | struct per_cpu_pageset *pset; |
713 | 713 | ||
714 | if (!populated_zone(zone)) | ||
715 | continue; | ||
716 | |||
714 | pset = zone_pcp(zone, cpu); | 717 | pset = zone_pcp(zone, cpu); |
715 | for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { | 718 | for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { |
716 | struct per_cpu_pages *pcp; | 719 | struct per_cpu_pages *pcp; |
@@ -3321,6 +3324,10 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
3321 | numentries >>= (scale - PAGE_SHIFT); | 3324 | numentries >>= (scale - PAGE_SHIFT); |
3322 | else | 3325 | else |
3323 | numentries <<= (PAGE_SHIFT - scale); | 3326 | numentries <<= (PAGE_SHIFT - scale); |
3327 | |||
3328 | /* Make sure we've got at least a 0-order allocation.. */ | ||
3329 | if (unlikely((numentries * bucketsize) < PAGE_SIZE)) | ||
3330 | numentries = PAGE_SIZE / bucketsize; | ||
3324 | } | 3331 | } |
3325 | numentries = roundup_pow_of_two(numentries); | 3332 | numentries = roundup_pow_of_two(numentries); |
3326 | 3333 | ||
@@ -3281,7 +3281,7 @@ retry: | |||
3281 | flags | GFP_THISNODE, nid); | 3281 | flags | GFP_THISNODE, nid); |
3282 | } | 3282 | } |
3283 | 3283 | ||
3284 | if (!obj) { | 3284 | if (!obj && !(flags & __GFP_NO_GROW)) { |
3285 | /* | 3285 | /* |
3286 | * This allocation will be performed within the constraints | 3286 | * This allocation will be performed within the constraints |
3287 | * of the current cpuset / memory policy requirements. | 3287 | * of the current cpuset / memory policy requirements. |
@@ -3310,7 +3310,7 @@ retry: | |||
3310 | */ | 3310 | */ |
3311 | goto retry; | 3311 | goto retry; |
3312 | } else { | 3312 | } else { |
3313 | kmem_freepages(cache, obj); | 3313 | /* cache_grow already freed obj */ |
3314 | obj = NULL; | 3314 | obj = NULL; |
3315 | } | 3315 | } |
3316 | } | 3316 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index b9fc0e5de6d5..a2d9bb4e80df 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -434,7 +434,7 @@ void free_swap_and_cache(swp_entry_t entry) | |||
434 | * | 434 | * |
435 | * This is needed for the suspend to disk (aka swsusp). | 435 | * This is needed for the suspend to disk (aka swsusp). |
436 | */ | 436 | */ |
437 | int swap_type_of(dev_t device, sector_t offset) | 437 | int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) |
438 | { | 438 | { |
439 | struct block_device *bdev = NULL; | 439 | struct block_device *bdev = NULL; |
440 | int i; | 440 | int i; |
@@ -450,6 +450,9 @@ int swap_type_of(dev_t device, sector_t offset) | |||
450 | continue; | 450 | continue; |
451 | 451 | ||
452 | if (!bdev) { | 452 | if (!bdev) { |
453 | if (bdev_p) | ||
454 | *bdev_p = sis->bdev; | ||
455 | |||
453 | spin_unlock(&swap_lock); | 456 | spin_unlock(&swap_lock); |
454 | return i; | 457 | return i; |
455 | } | 458 | } |
@@ -459,6 +462,9 @@ int swap_type_of(dev_t device, sector_t offset) | |||
459 | se = list_entry(sis->extent_list.next, | 462 | se = list_entry(sis->extent_list.next, |
460 | struct swap_extent, list); | 463 | struct swap_extent, list); |
461 | if (se->start_block == offset) { | 464 | if (se->start_block == offset) { |
465 | if (bdev_p) | ||
466 | *bdev_p = sis->bdev; | ||
467 | |||
462 | spin_unlock(&swap_lock); | 468 | spin_unlock(&swap_lock); |
463 | bdput(bdev); | 469 | bdput(bdev); |
464 | return i; | 470 | return i; |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 40fea4918390..7430df68cb64 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1406,6 +1406,16 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio, | |||
1406 | return ret; | 1406 | return ret; |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | static unsigned long count_lru_pages(void) | ||
1410 | { | ||
1411 | struct zone *zone; | ||
1412 | unsigned long ret = 0; | ||
1413 | |||
1414 | for_each_zone(zone) | ||
1415 | ret += zone->nr_active + zone->nr_inactive; | ||
1416 | return ret; | ||
1417 | } | ||
1418 | |||
1409 | /* | 1419 | /* |
1410 | * Try to free `nr_pages' of memory, system-wide, and return the number of | 1420 | * Try to free `nr_pages' of memory, system-wide, and return the number of |
1411 | * freed pages. | 1421 | * freed pages. |
@@ -1420,7 +1430,6 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
1420 | unsigned long ret = 0; | 1430 | unsigned long ret = 0; |
1421 | int pass; | 1431 | int pass; |
1422 | struct reclaim_state reclaim_state; | 1432 | struct reclaim_state reclaim_state; |
1423 | struct zone *zone; | ||
1424 | struct scan_control sc = { | 1433 | struct scan_control sc = { |
1425 | .gfp_mask = GFP_KERNEL, | 1434 | .gfp_mask = GFP_KERNEL, |
1426 | .may_swap = 0, | 1435 | .may_swap = 0, |
@@ -1431,10 +1440,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
1431 | 1440 | ||
1432 | current->reclaim_state = &reclaim_state; | 1441 | current->reclaim_state = &reclaim_state; |
1433 | 1442 | ||
1434 | lru_pages = 0; | 1443 | lru_pages = count_lru_pages(); |
1435 | for_each_zone(zone) | ||
1436 | lru_pages += zone->nr_active + zone->nr_inactive; | ||
1437 | |||
1438 | nr_slab = global_page_state(NR_SLAB_RECLAIMABLE); | 1444 | nr_slab = global_page_state(NR_SLAB_RECLAIMABLE); |
1439 | /* If slab caches are huge, it's better to hit them first */ | 1445 | /* If slab caches are huge, it's better to hit them first */ |
1440 | while (nr_slab >= lru_pages) { | 1446 | while (nr_slab >= lru_pages) { |
@@ -1461,13 +1467,6 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
1461 | for (pass = 0; pass < 5; pass++) { | 1467 | for (pass = 0; pass < 5; pass++) { |
1462 | int prio; | 1468 | int prio; |
1463 | 1469 | ||
1464 | /* Needed for shrinking slab caches later on */ | ||
1465 | if (!lru_pages) | ||
1466 | for_each_zone(zone) { | ||
1467 | lru_pages += zone->nr_active; | ||
1468 | lru_pages += zone->nr_inactive; | ||
1469 | } | ||
1470 | |||
1471 | /* Force reclaiming mapped pages in the passes #3 and #4 */ | 1470 | /* Force reclaiming mapped pages in the passes #3 and #4 */ |
1472 | if (pass > 2) { | 1471 | if (pass > 2) { |
1473 | sc.may_swap = 1; | 1472 | sc.may_swap = 1; |
@@ -1483,7 +1482,8 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
1483 | goto out; | 1482 | goto out; |
1484 | 1483 | ||
1485 | reclaim_state.reclaimed_slab = 0; | 1484 | reclaim_state.reclaimed_slab = 0; |
1486 | shrink_slab(sc.nr_scanned, sc.gfp_mask, lru_pages); | 1485 | shrink_slab(sc.nr_scanned, sc.gfp_mask, |
1486 | count_lru_pages()); | ||
1487 | ret += reclaim_state.reclaimed_slab; | 1487 | ret += reclaim_state.reclaimed_slab; |
1488 | if (ret >= nr_pages) | 1488 | if (ret >= nr_pages) |
1489 | goto out; | 1489 | goto out; |
@@ -1491,20 +1491,19 @@ unsigned long shrink_all_memory(unsigned long nr_pages) | |||
1491 | if (sc.nr_scanned && prio < DEF_PRIORITY - 2) | 1491 | if (sc.nr_scanned && prio < DEF_PRIORITY - 2) |
1492 | congestion_wait(WRITE, HZ / 10); | 1492 | congestion_wait(WRITE, HZ / 10); |
1493 | } | 1493 | } |
1494 | |||
1495 | lru_pages = 0; | ||
1496 | } | 1494 | } |
1497 | 1495 | ||
1498 | /* | 1496 | /* |
1499 | * If ret = 0, we could not shrink LRUs, but there may be something | 1497 | * If ret = 0, we could not shrink LRUs, but there may be something |
1500 | * in slab caches | 1498 | * in slab caches |
1501 | */ | 1499 | */ |
1502 | if (!ret) | 1500 | if (!ret) { |
1503 | do { | 1501 | do { |
1504 | reclaim_state.reclaimed_slab = 0; | 1502 | reclaim_state.reclaimed_slab = 0; |
1505 | shrink_slab(nr_pages, sc.gfp_mask, lru_pages); | 1503 | shrink_slab(nr_pages, sc.gfp_mask, count_lru_pages()); |
1506 | ret += reclaim_state.reclaimed_slab; | 1504 | ret += reclaim_state.reclaimed_slab; |
1507 | } while (ret < nr_pages && reclaim_state.reclaimed_slab > 0); | 1505 | } while (ret < nr_pages && reclaim_state.reclaimed_slab > 0); |
1506 | } | ||
1508 | 1507 | ||
1509 | out: | 1508 | out: |
1510 | current->reclaim_state = NULL; | 1509 | current->reclaim_state = NULL; |