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(); |
