aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/vmscan.c34
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 */
2713static int kswapd(void *p) 2715static 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();