]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/vmscan.c
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux.git] / mm / vmscan.c
index 7889f583ced9fef1319cadf94a8e2ca7d9d4c40e..910e02c793ffc273d4578b2c68f47a0fe33b8412 100644 (file)
@@ -3644,19 +3644,18 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
 }
 
 /*
- * pgdat->kswapd_classzone_idx is the highest zone index that a recent
- * allocation request woke kswapd for. When kswapd has not woken recently,
- * the value is MAX_NR_ZONES which is not a valid index. This compares a
- * given classzone and returns it or the highest classzone index kswapd
- * was recently woke for.
+ * The pgdat->kswapd_classzone_idx is used to pass the highest zone index to be
+ * reclaimed by kswapd from the waker. If the value is MAX_NR_ZONES which is not
+ * a valid index then either kswapd runs for first time or kswapd couldn't sleep
+ * after previous reclaim attempt (node is still unbalanced). In that case
+ * return the zone index of the previous kswapd reclaim cycle.
  */
 static enum zone_type kswapd_classzone_idx(pg_data_t *pgdat,
-                                          enum zone_type classzone_idx)
+                                          enum zone_type prev_classzone_idx)
 {
        if (pgdat->kswapd_classzone_idx == MAX_NR_ZONES)
-               return classzone_idx;
-
-       return max(pgdat->kswapd_classzone_idx, classzone_idx);
+               return prev_classzone_idx;
+       return pgdat->kswapd_classzone_idx;
 }
 
 static void kswapd_try_to_sleep(pg_data_t *pgdat, int alloc_order, int reclaim_order,
@@ -3797,7 +3796,7 @@ static int kswapd(void *p)
 
                /* Read the new order and classzone_idx */
                alloc_order = reclaim_order = pgdat->kswapd_order;
-               classzone_idx = kswapd_classzone_idx(pgdat, 0);
+               classzone_idx = kswapd_classzone_idx(pgdat, classzone_idx);
                pgdat->kswapd_order = 0;
                pgdat->kswapd_classzone_idx = MAX_NR_ZONES;
 
@@ -3851,8 +3850,12 @@ void wakeup_kswapd(struct zone *zone, gfp_t gfp_flags, int order,
        if (!cpuset_zone_allowed(zone, gfp_flags))
                return;
        pgdat = zone->zone_pgdat;
-       pgdat->kswapd_classzone_idx = kswapd_classzone_idx(pgdat,
-                                                          classzone_idx);
+
+       if (pgdat->kswapd_classzone_idx == MAX_NR_ZONES)
+               pgdat->kswapd_classzone_idx = classzone_idx;
+       else
+               pgdat->kswapd_classzone_idx = max(pgdat->kswapd_classzone_idx,
+                                                 classzone_idx);
        pgdat->kswapd_order = max(pgdat->kswapd_order, order);
        if (!waitqueue_active(&pgdat->kswapd_wait))
                return;