2010-07-07 11:12:45 +00:00
|
|
|
From: Nick Piggin <npiggin@suse.de>
|
|
|
|
Subject: be more aggressive with zone reclaims
|
|
|
|
References: bnc#476525
|
|
|
|
Patch-mainline: no
|
|
|
|
|
|
|
|
The zone reclaim design is not very good for parallel allocations.
|
|
|
|
The primary problem is that only one thread is allowed to perform
|
|
|
|
zone-reclaim at a time. If another thread needs memory from that
|
|
|
|
zone/node, then its zone-reclaim will fail and it will be forced
|
|
|
|
to fall back to allocating from another zone.
|
|
|
|
|
|
|
|
Additionally, the default zone reclaim priority is insufficient
|
|
|
|
for massively parallel allocations. Lower ZONE_RECLAIM_PRIORITY
|
|
|
|
to fix it. This can result in higher latency spikes, but similar
|
|
|
|
kind of page allocation latency can often be encountered as
|
|
|
|
normal part of page reclaim when pagecache fills memory.
|
|
|
|
|
|
|
|
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
|
|
|
|
|
|
|
|
---
|
|
|
|
mm/vmscan.c | 13 ++++---------
|
|
|
|
1 file changed, 4 insertions(+), 9 deletions(-)
|
|
|
|
|
|
|
|
--- a/mm/vmscan.c
|
|
|
|
+++ b/mm/vmscan.c
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -2515,7 +2515,7 @@ int zone_reclaim_mode __read_mostly;
|
2010-07-07 11:12:45 +00:00
|
|
|
* of a node considered for each zone_reclaim. 4 scans 1/16th of
|
|
|
|
* a zone.
|
|
|
|
*/
|
|
|
|
-#define ZONE_RECLAIM_PRIORITY 4
|
|
|
|
+#define ZONE_RECLAIM_PRIORITY 0
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Percentage of pages in a zone that must be unmapped for zone_reclaim to
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -2620,6 +2620,8 @@ static int __zone_reclaim(struct zone *z
|
2010-07-07 11:12:45 +00:00
|
|
|
|
|
|
|
slab_reclaimable = zone_page_state(zone, NR_SLAB_RECLAIMABLE);
|
|
|
|
if (slab_reclaimable > zone->min_slab_pages) {
|
|
|
|
+ unsigned long lru_pages = zone_reclaimable_pages(zone);
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* shrink_slab() does not currently allow us to determine how
|
|
|
|
* many pages were freed in this zone. So we take the current
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -2630,10 +2632,7 @@ static int __zone_reclaim(struct zone *z
|
2010-07-07 11:12:45 +00:00
|
|
|
* Note that shrink_slab will free memory on all zones and may
|
|
|
|
* take a long time.
|
|
|
|
*/
|
|
|
|
- while (shrink_slab(sc.nr_scanned, gfp_mask, order) &&
|
|
|
|
- zone_page_state(zone, NR_SLAB_RECLAIMABLE) >
|
|
|
|
- slab_reclaimable - nr_pages)
|
|
|
|
- ;
|
|
|
|
+ shrink_slab(sc.nr_scanned, gfp_mask, lru_pages);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update nr_reclaimed by the number of slab pages we
|
2011-04-19 20:09:59 +00:00
|
|
|
@@ -2687,11 +2686,7 @@ int zone_reclaim(struct zone *zone, gfp_
|
2010-07-07 11:12:45 +00:00
|
|
|
if (node_state(node_id, N_CPU) && node_id != numa_node_id())
|
|
|
|
return ZONE_RECLAIM_NOSCAN;
|
|
|
|
|
|
|
|
- if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
|
|
|
|
- return ZONE_RECLAIM_NOSCAN;
|
|
|
|
-
|
|
|
|
ret = __zone_reclaim(zone, gfp_mask, order);
|
|
|
|
- zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
|
|
|
|
|
|
|
|
if (!ret)
|
|
|
|
count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED);
|