diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2014-08-06 19:06:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 21:01:18 -0400 |
commit | 2344d7e44b870f9df67e505ee4e633217de752ba (patch) | |
tree | 0160199022d9231c1b84ab6f275fdd429acb0e43 /mm | |
parent | 0b06496a338e83627dc5f0d25323e7a1ae9cb87d (diff) |
mm: vmscan: remove all_unreclaimable()
Direct reclaim currently calls shrink_zones() to reclaim all members of
a zonelist, and if that wasn't successful it does another pass through
the same zonelist to check overall reclaimability.
Just check reclaimability in shrink_zones() directly and propagate the
result through the return value. Then remove all_unreclaimable().
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
Cc: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/vmscan.c | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 6f43df4a5253..74a9e0ae09b0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2244,9 +2244,10 @@ static inline bool should_continue_reclaim(struct zone *zone, | |||
2244 | } | 2244 | } |
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | static void shrink_zone(struct zone *zone, struct scan_control *sc) | 2247 | static bool shrink_zone(struct zone *zone, struct scan_control *sc) |
2248 | { | 2248 | { |
2249 | unsigned long nr_reclaimed, nr_scanned; | 2249 | unsigned long nr_reclaimed, nr_scanned; |
2250 | bool reclaimable = false; | ||
2250 | 2251 | ||
2251 | do { | 2252 | do { |
2252 | struct mem_cgroup *root = sc->target_mem_cgroup; | 2253 | struct mem_cgroup *root = sc->target_mem_cgroup; |
@@ -2290,8 +2291,13 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc) | |||
2290 | sc->nr_scanned - nr_scanned, | 2291 | sc->nr_scanned - nr_scanned, |
2291 | sc->nr_reclaimed - nr_reclaimed); | 2292 | sc->nr_reclaimed - nr_reclaimed); |
2292 | 2293 | ||
2294 | if (sc->nr_reclaimed - nr_reclaimed) | ||
2295 | reclaimable = true; | ||
2296 | |||
2293 | } while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed, | 2297 | } while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed, |
2294 | sc->nr_scanned - nr_scanned, sc)); | 2298 | sc->nr_scanned - nr_scanned, sc)); |
2299 | |||
2300 | return reclaimable; | ||
2295 | } | 2301 | } |
2296 | 2302 | ||
2297 | /* Returns true if compaction should go ahead for a high-order request */ | 2303 | /* Returns true if compaction should go ahead for a high-order request */ |
@@ -2340,8 +2346,10 @@ static inline bool compaction_ready(struct zone *zone, int order) | |||
2340 | * | 2346 | * |
2341 | * If a zone is deemed to be full of pinned pages then just give it a light | 2347 | * If a zone is deemed to be full of pinned pages then just give it a light |
2342 | * scan then give up on it. | 2348 | * scan then give up on it. |
2349 | * | ||
2350 | * Returns true if a zone was reclaimable. | ||
2343 | */ | 2351 | */ |
2344 | static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | 2352 | static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) |
2345 | { | 2353 | { |
2346 | struct zoneref *z; | 2354 | struct zoneref *z; |
2347 | struct zone *zone; | 2355 | struct zone *zone; |
@@ -2354,6 +2362,7 @@ static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | |||
2354 | .gfp_mask = sc->gfp_mask, | 2362 | .gfp_mask = sc->gfp_mask, |
2355 | }; | 2363 | }; |
2356 | enum zone_type requested_highidx = gfp_zone(sc->gfp_mask); | 2364 | enum zone_type requested_highidx = gfp_zone(sc->gfp_mask); |
2365 | bool reclaimable = false; | ||
2357 | 2366 | ||
2358 | /* | 2367 | /* |
2359 | * If the number of buffer_heads in the machine exceeds the maximum | 2368 | * If the number of buffer_heads in the machine exceeds the maximum |
@@ -2414,10 +2423,17 @@ static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | |||
2414 | &nr_soft_scanned); | 2423 | &nr_soft_scanned); |
2415 | sc->nr_reclaimed += nr_soft_reclaimed; | 2424 | sc->nr_reclaimed += nr_soft_reclaimed; |
2416 | sc->nr_scanned += nr_soft_scanned; | 2425 | sc->nr_scanned += nr_soft_scanned; |
2426 | if (nr_soft_reclaimed) | ||
2427 | reclaimable = true; | ||
2417 | /* need some check for avoid more shrink_zone() */ | 2428 | /* need some check for avoid more shrink_zone() */ |
2418 | } | 2429 | } |
2419 | 2430 | ||
2420 | shrink_zone(zone, sc); | 2431 | if (shrink_zone(zone, sc)) |
2432 | reclaimable = true; | ||
2433 | |||
2434 | if (global_reclaim(sc) && | ||
2435 | !reclaimable && zone_reclaimable(zone)) | ||
2436 | reclaimable = true; | ||
2421 | } | 2437 | } |
2422 | 2438 | ||
2423 | /* | 2439 | /* |
@@ -2439,26 +2455,8 @@ static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | |||
2439 | * promoted it to __GFP_HIGHMEM. | 2455 | * promoted it to __GFP_HIGHMEM. |
2440 | */ | 2456 | */ |
2441 | sc->gfp_mask = orig_mask; | 2457 | sc->gfp_mask = orig_mask; |
2442 | } | ||
2443 | |||
2444 | /* All zones in zonelist are unreclaimable? */ | ||
2445 | static bool all_unreclaimable(struct zonelist *zonelist, | ||
2446 | struct scan_control *sc) | ||
2447 | { | ||
2448 | struct zoneref *z; | ||
2449 | struct zone *zone; | ||
2450 | 2458 | ||
2451 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 2459 | return reclaimable; |
2452 | gfp_zone(sc->gfp_mask), sc->nodemask) { | ||
2453 | if (!populated_zone(zone)) | ||
2454 | continue; | ||
2455 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | ||
2456 | continue; | ||
2457 | if (zone_reclaimable(zone)) | ||
2458 | return false; | ||
2459 | } | ||
2460 | |||
2461 | return true; | ||
2462 | } | 2460 | } |
2463 | 2461 | ||
2464 | /* | 2462 | /* |
@@ -2482,6 +2480,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
2482 | { | 2480 | { |
2483 | unsigned long total_scanned = 0; | 2481 | unsigned long total_scanned = 0; |
2484 | unsigned long writeback_threshold; | 2482 | unsigned long writeback_threshold; |
2483 | bool zones_reclaimable; | ||
2485 | 2484 | ||
2486 | delayacct_freepages_start(); | 2485 | delayacct_freepages_start(); |
2487 | 2486 | ||
@@ -2492,7 +2491,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
2492 | vmpressure_prio(sc->gfp_mask, sc->target_mem_cgroup, | 2491 | vmpressure_prio(sc->gfp_mask, sc->target_mem_cgroup, |
2493 | sc->priority); | 2492 | sc->priority); |
2494 | sc->nr_scanned = 0; | 2493 | sc->nr_scanned = 0; |
2495 | shrink_zones(zonelist, sc); | 2494 | zones_reclaimable = shrink_zones(zonelist, sc); |
2496 | 2495 | ||
2497 | total_scanned += sc->nr_scanned; | 2496 | total_scanned += sc->nr_scanned; |
2498 | if (sc->nr_reclaimed >= sc->nr_to_reclaim) | 2497 | if (sc->nr_reclaimed >= sc->nr_to_reclaim) |
@@ -2532,8 +2531,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
2532 | if (sc->compaction_ready) | 2531 | if (sc->compaction_ready) |
2533 | return 1; | 2532 | return 1; |
2534 | 2533 | ||
2535 | /* top priority shrink_zones still had more to do? don't OOM, then */ | 2534 | /* Any of the zones still reclaimable? Don't OOM. */ |
2536 | if (global_reclaim(sc) && !all_unreclaimable(zonelist, sc)) | 2535 | if (zones_reclaimable) |
2537 | return 1; | 2536 | return 1; |
2538 | 2537 | ||
2539 | return 0; | 2538 | return 0; |