Commit d2ebd0f6b89567eb93ead4e2ca0cbe03021f344b

Authored by Alex,Shi
Committed by Linus Torvalds
1 parent 64212ec569

kswapd: avoid unnecessary rebalance after an unsuccessful balancing

In commit 215ddd66 ("mm: vmscan: only read new_classzone_idx from pgdat
when reclaiming successfully") , Mel Gorman said kswapd is better to sleep
after a unsuccessful balancing if there is tighter reclaim request pending
in the balancing.  But in the following scenario, kswapd do something that
is not matched our expectation.  The patch fixes this issue.

1, Read pgdat request A (classzone_idx, order = 3)
2, balance_pgdat()
3, During pgdat, a new pgdat request B (classzone_idx, order = 5) is placed
4, balance_pgdat() returns but failed since returned order = 0
5, pgdat of request A assigned to balance_pgdat(), and do balancing again.
   While the expectation behavior of kswapd should try to sleep.

Signed-off-by: Alex Shi <alex.shi@intel.com>
Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Tested-by: Pádraig Brady <P@draigBrady.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 11 additions and 3 deletions Side-by-side Diff

... ... @@ -2823,7 +2823,9 @@
2823 2823 static int kswapd(void *p)
2824 2824 {
2825 2825 unsigned long order, new_order;
  2826 + unsigned balanced_order;
2826 2827 int classzone_idx, new_classzone_idx;
  2828 + int balanced_classzone_idx;
2827 2829 pg_data_t *pgdat = (pg_data_t*)p;
2828 2830 struct task_struct *tsk = current;
2829 2831  
2830 2832  
... ... @@ -2854,7 +2856,9 @@
2854 2856 set_freezable();
2855 2857  
2856 2858 order = new_order = 0;
  2859 + balanced_order = 0;
2857 2860 classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
  2861 + balanced_classzone_idx = classzone_idx;
2858 2862 for ( ; ; ) {
2859 2863 int ret;
2860 2864  
... ... @@ -2863,7 +2867,8 @@
2863 2867 * new request of a similar or harder type will succeed soon
2864 2868 * so consider going to sleep on the basis we reclaimed at
2865 2869 */
2866   - if (classzone_idx >= new_classzone_idx && order == new_order) {
  2870 + if (balanced_classzone_idx >= new_classzone_idx &&
  2871 + balanced_order == new_order) {
2867 2872 new_order = pgdat->kswapd_max_order;
2868 2873 new_classzone_idx = pgdat->classzone_idx;
2869 2874 pgdat->kswapd_max_order = 0;
... ... @@ -2878,7 +2883,8 @@
2878 2883 order = new_order;
2879 2884 classzone_idx = new_classzone_idx;
2880 2885 } else {
2881   - kswapd_try_to_sleep(pgdat, order, classzone_idx);
  2886 + kswapd_try_to_sleep(pgdat, balanced_order,
  2887 + balanced_classzone_idx);
2882 2888 order = pgdat->kswapd_max_order;
2883 2889 classzone_idx = pgdat->classzone_idx;
2884 2890 pgdat->kswapd_max_order = 0;
... ... @@ -2895,7 +2901,9 @@
2895 2901 */
2896 2902 if (!ret) {
2897 2903 trace_mm_vmscan_kswapd_wake(pgdat->node_id, order);
2898   - order = balance_pgdat(pgdat, order, &classzone_idx);
  2904 + balanced_classzone_idx = classzone_idx;
  2905 + balanced_order = balance_pgdat(pgdat, order,
  2906 + &balanced_classzone_idx);
2899 2907 }
2900 2908 }
2901 2909 return 0;