diff options
-rw-r--r-- | mm/vmscan.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index a51b3c9f05ba..5ed24b94c5e6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2451,7 +2451,6 @@ loop_again: | |||
2451 | if (!zone_watermark_ok_safe(zone, order, | 2451 | if (!zone_watermark_ok_safe(zone, order, |
2452 | high_wmark_pages(zone), 0, 0)) { | 2452 | high_wmark_pages(zone), 0, 0)) { |
2453 | end_zone = i; | 2453 | end_zone = i; |
2454 | *classzone_idx = i; | ||
2455 | break; | 2454 | break; |
2456 | } | 2455 | } |
2457 | } | 2456 | } |
@@ -2531,8 +2530,11 @@ loop_again: | |||
2531 | total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) | 2530 | total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) |
2532 | sc.may_writepage = 1; | 2531 | sc.may_writepage = 1; |
2533 | 2532 | ||
2534 | if (zone->all_unreclaimable) | 2533 | if (zone->all_unreclaimable) { |
2534 | if (end_zone && end_zone == i) | ||
2535 | end_zone--; | ||
2535 | continue; | 2536 | continue; |
2537 | } | ||
2536 | 2538 | ||
2537 | if (!zone_watermark_ok_safe(zone, order, | 2539 | if (!zone_watermark_ok_safe(zone, order, |
2538 | high_wmark_pages(zone), end_zone, 0)) { | 2540 | high_wmark_pages(zone), end_zone, 0)) { |
@@ -2712,8 +2714,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) | |||
2712 | */ | 2714 | */ |
2713 | static int kswapd(void *p) | 2715 | static int kswapd(void *p) |
2714 | { | 2716 | { |
2715 | unsigned long order; | 2717 | unsigned long order, new_order; |
2716 | int classzone_idx; | 2718 | int classzone_idx, new_classzone_idx; |
2717 | pg_data_t *pgdat = (pg_data_t*)p; | 2719 | pg_data_t *pgdat = (pg_data_t*)p; |
2718 | struct task_struct *tsk = current; | 2720 | struct task_struct *tsk = current; |
2719 | 2721 | ||
@@ -2743,17 +2745,23 @@ static int kswapd(void *p) | |||
2743 | tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; | 2745 | tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; |
2744 | set_freezable(); | 2746 | set_freezable(); |
2745 | 2747 | ||
2746 | order = 0; | 2748 | order = new_order = 0; |
2747 | classzone_idx = MAX_NR_ZONES - 1; | 2749 | classzone_idx = new_classzone_idx = pgdat->nr_zones - 1; |
2748 | for ( ; ; ) { | 2750 | for ( ; ; ) { |
2749 | unsigned long new_order; | ||
2750 | int new_classzone_idx; | ||
2751 | int ret; | 2751 | int ret; |
2752 | 2752 | ||
2753 | new_order = pgdat->kswapd_max_order; | 2753 | /* |
2754 | new_classzone_idx = pgdat->classzone_idx; | 2754 | * If the last balance_pgdat was unsuccessful it's unlikely a |
2755 | pgdat->kswapd_max_order = 0; | 2755 | * new request of a similar or harder type will succeed soon |
2756 | pgdat->classzone_idx = MAX_NR_ZONES - 1; | 2756 | * so consider going to sleep on the basis we reclaimed at |
2757 | */ | ||
2758 | if (classzone_idx >= new_classzone_idx && order == new_order) { | ||
2759 | new_order = pgdat->kswapd_max_order; | ||
2760 | new_classzone_idx = pgdat->classzone_idx; | ||
2761 | pgdat->kswapd_max_order = 0; | ||
2762 | pgdat->classzone_idx = pgdat->nr_zones - 1; | ||
2763 | } | ||
2764 | |||
2757 | if (order < new_order || classzone_idx > new_classzone_idx) { | 2765 | if (order < new_order || classzone_idx > new_classzone_idx) { |
2758 | /* | 2766 | /* |
2759 | * Don't sleep if someone wants a larger 'order' | 2767 | * Don't sleep if someone wants a larger 'order' |
@@ -2766,7 +2774,7 @@ static int kswapd(void *p) | |||
2766 | order = pgdat->kswapd_max_order; | 2774 | order = pgdat->kswapd_max_order; |
2767 | classzone_idx = pgdat->classzone_idx; | 2775 | classzone_idx = pgdat->classzone_idx; |
2768 | pgdat->kswapd_max_order = 0; | 2776 | pgdat->kswapd_max_order = 0; |
2769 | pgdat->classzone_idx = MAX_NR_ZONES - 1; | 2777 | pgdat->classzone_idx = pgdat->nr_zones - 1; |
2770 | } | 2778 | } |
2771 | 2779 | ||
2772 | ret = try_to_freeze(); | 2780 | ret = try_to_freeze(); |