aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
authorAlex,Shi <alex.shi@intel.com>2011-10-31 20:08:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 20:30:48 -0400
commitd2ebd0f6b89567eb93ead4e2ca0cbe03021f344b (patch)
tree1f8fc3f7702a8b4d362f5537e135e96f86043f8d /mm/vmscan.c
parent64212ec569bfdd094f7a23d9b09862209a983559 (diff)
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>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 77ee24fc891a..dd5fc86dbb82 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2823,7 +2823,9 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
2823static int kswapd(void *p) 2823static int kswapd(void *p)
2824{ 2824{
2825 unsigned long order, new_order; 2825 unsigned long order, new_order;
2826 unsigned balanced_order;
2826 int classzone_idx, new_classzone_idx; 2827 int classzone_idx, new_classzone_idx;
2828 int balanced_classzone_idx;
2827 pg_data_t *pgdat = (pg_data_t*)p; 2829 pg_data_t *pgdat = (pg_data_t*)p;
2828 struct task_struct *tsk = current; 2830 struct task_struct *tsk = current;
2829 2831
@@ -2854,7 +2856,9 @@ static int kswapd(void *p)
2854 set_freezable(); 2856 set_freezable();
2855 2857
2856 order = new_order = 0; 2858 order = new_order = 0;
2859 balanced_order = 0;
2857 classzone_idx = new_classzone_idx = pgdat->nr_zones - 1; 2860 classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
2861 balanced_classzone_idx = classzone_idx;
2858 for ( ; ; ) { 2862 for ( ; ; ) {
2859 int ret; 2863 int ret;
2860 2864
@@ -2863,7 +2867,8 @@ static int kswapd(void *p)
2863 * new request of a similar or harder type will succeed soon 2867 * new request of a similar or harder type will succeed soon
2864 * so consider going to sleep on the basis we reclaimed at 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 new_order = pgdat->kswapd_max_order; 2872 new_order = pgdat->kswapd_max_order;
2868 new_classzone_idx = pgdat->classzone_idx; 2873 new_classzone_idx = pgdat->classzone_idx;
2869 pgdat->kswapd_max_order = 0; 2874 pgdat->kswapd_max_order = 0;
@@ -2878,7 +2883,8 @@ static int kswapd(void *p)
2878 order = new_order; 2883 order = new_order;
2879 classzone_idx = new_classzone_idx; 2884 classzone_idx = new_classzone_idx;
2880 } else { 2885 } else {
2881 kswapd_try_to_sleep(pgdat, order, classzone_idx); 2886 kswapd_try_to_sleep(pgdat, balanced_order,
2887 balanced_classzone_idx);
2882 order = pgdat->kswapd_max_order; 2888 order = pgdat->kswapd_max_order;
2883 classzone_idx = pgdat->classzone_idx; 2889 classzone_idx = pgdat->classzone_idx;
2884 pgdat->kswapd_max_order = 0; 2890 pgdat->kswapd_max_order = 0;
@@ -2895,7 +2901,9 @@ static int kswapd(void *p)
2895 */ 2901 */
2896 if (!ret) { 2902 if (!ret) {
2897 trace_mm_vmscan_kswapd_wake(pgdat->node_id, order); 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 return 0; 2909 return 0;