kswapd scans from highest to lowest for a zone that requires balancing.
This was necessary when reclaim was per-zone to fairly age pages on
lower zones. Now that we are reclaiming on a per-node basis, any eligible
zone can be used and pages will still be aged fairly. This patch avoids
reclaiming excessively unless buffer_heads are over the limit and it's
necessary to reclaim from a higher zone than requested by the waker of
kswapd to relieve low memory pressure.

Signed-off-by: Mel Gorman <mgor...@techsingularity.net>
---
 mm/vmscan.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1f5d3829d35e..39ad2ab76a2b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3123,24 +3123,30 @@ static int balance_pgdat(pg_data_t *pgdat, int order, 
int classzone_idx)
 
                sc.nr_reclaimed = 0;
 
-               /* Scan from the highest requested zone to dma */
+               /*
+                * If the number of buffer_heads in the machine exceeds the
+                * maximum allowed level and this node has a highmem zone,
+                * force kswapd to reclaim from it to relieve lowmem pressure.
+                */
+               if (buffer_heads_over_limit) {
+                       for (i = MAX_NR_ZONES - 1; i >= 0; i++) {
+                               zone = pgdat->node_zones + i;
+                               if (!populated_zone(zone))
+                                       continue;
+
+                               if (is_highmem_idx(i))
+                                       classzone_idx = i;
+                               break;
+                       }
+               }
+
+               /* Only reclaim if there are no eligible zones */
                for (i = classzone_idx; i >= 0; i--) {
                        zone = pgdat->node_zones + i;
                        if (!populated_zone(zone))
                                continue;
 
-                       /*
-                        * If the number of buffer_heads in the machine
-                        * exceeds the maximum allowed level and this node
-                        * has a highmem zone, force kswapd to reclaim from
-                        * it to relieve lowmem pressure.
-                        */
-                       if (buffer_heads_over_limit && is_highmem_idx(i)) {
-                               classzone_idx = i;
-                               break;
-                       }
-
-                       if (!zone_balanced(zone, order, 0, 0)) {
+                       if (!zone_balanced(zone, order, 0, classzone_idx)) {
                                classzone_idx = i;
                                break;
                        }
-- 
2.6.4

Reply via email to