aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7889f583ced9..910e02c793ff 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3644,19 +3644,18 @@ out:
3644} 3644}
3645 3645
3646/* 3646/*
3647 * pgdat->kswapd_classzone_idx is the highest zone index that a recent 3647 * The pgdat->kswapd_classzone_idx is used to pass the highest zone index to be
3648 * allocation request woke kswapd for. When kswapd has not woken recently, 3648 * reclaimed by kswapd from the waker. If the value is MAX_NR_ZONES which is not
3649 * the value is MAX_NR_ZONES which is not a valid index. This compares a 3649 * a valid index then either kswapd runs for first time or kswapd couldn't sleep
3650 * given classzone and returns it or the highest classzone index kswapd 3650 * after previous reclaim attempt (node is still unbalanced). In that case
3651 * was recently woke for. 3651 * return the zone index of the previous kswapd reclaim cycle.
3652 */ 3652 */
3653static enum zone_type kswapd_classzone_idx(pg_data_t *pgdat, 3653static enum zone_type kswapd_classzone_idx(pg_data_t *pgdat,
3654 enum zone_type classzone_idx) 3654 enum zone_type prev_classzone_idx)
3655{ 3655{
3656 if (pgdat->kswapd_classzone_idx == MAX_NR_ZONES) 3656 if (pgdat->kswapd_classzone_idx == MAX_NR_ZONES)
3657 return classzone_idx; 3657 return prev_classzone_idx;
3658 3658 return pgdat->kswapd_classzone_idx;
3659 return max(pgdat->kswapd_classzone_idx, classzone_idx);
3660} 3659}
3661 3660
3662static void kswapd_try_to_sleep(pg_data_t *pgdat, int alloc_order, int reclaim_order, 3661static void kswapd_try_to_sleep(pg_data_t *pgdat, int alloc_order, int reclaim_order,
@@ -3797,7 +3796,7 @@ kswapd_try_sleep:
3797 3796
3798 /* Read the new order and classzone_idx */ 3797 /* Read the new order and classzone_idx */
3799 alloc_order = reclaim_order = pgdat->kswapd_order; 3798 alloc_order = reclaim_order = pgdat->kswapd_order;
3800 classzone_idx = kswapd_classzone_idx(pgdat, 0); 3799 classzone_idx = kswapd_classzone_idx(pgdat, classzone_idx);
3801 pgdat->kswapd_order = 0; 3800 pgdat->kswapd_order = 0;
3802 pgdat->kswapd_classzone_idx = MAX_NR_ZONES; 3801 pgdat->kswapd_classzone_idx = MAX_NR_ZONES;
3803 3802
@@ -3851,8 +3850,12 @@ void wakeup_kswapd(struct zone *zone, gfp_t gfp_flags, int order,
3851 if (!cpuset_zone_allowed(zone, gfp_flags)) 3850 if (!cpuset_zone_allowed(zone, gfp_flags))
3852 return; 3851 return;
3853 pgdat = zone->zone_pgdat; 3852 pgdat = zone->zone_pgdat;
3854 pgdat->kswapd_classzone_idx = kswapd_classzone_idx(pgdat, 3853
3855 classzone_idx); 3854 if (pgdat->kswapd_classzone_idx == MAX_NR_ZONES)
3855 pgdat->kswapd_classzone_idx = classzone_idx;
3856 else
3857 pgdat->kswapd_classzone_idx = max(pgdat->kswapd_classzone_idx,
3858 classzone_idx);
3856 pgdat->kswapd_order = max(pgdat->kswapd_order, order); 3859 pgdat->kswapd_order = max(pgdat->kswapd_order, order);
3857 if (!waitqueue_active(&pgdat->kswapd_wait)) 3860 if (!waitqueue_active(&pgdat->kswapd_wait))
3858 return; 3861 return;