Subject: writeback: scale dirty proportions period with writeout bandwidth Date: Sat Apr 16 18:38:41 CST 2011 CC: Peter Zijlstra Signed-off-by: Wu Fengguang --- mm/page-writeback.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) --- linux-next.orig/mm/page-writeback.c 2011-04-17 20:52:13.000000000 +0800 +++ linux-next/mm/page-writeback.c 2011-04-18 16:06:03.000000000 +0800 @@ -121,20 +121,15 @@ static struct prop_descriptor vm_complet static struct prop_descriptor vm_dirties; /* - * couple the period to the dirty_ratio: + * couple the period to global write throughput: * - * period/2 ~ roundup_pow_of_two(dirty limit) + * period/2 ~ roundup_pow_of_two(write IO throughput) */ static int calc_period_shift(void) { - unsigned long dirty_total; + unsigned long bw = default_backing_dev_info.avg_write_bandwidth; - if (vm_dirty_bytes) - dirty_total = vm_dirty_bytes / PAGE_SIZE; - else - dirty_total = (vm_dirty_ratio * determine_dirtyable_memory()) / - 100; - return 2 + ilog2(dirty_total - 1); + return 2 + ilog2(bw); } /* @@ -143,6 +138,14 @@ static int calc_period_shift(void) static void update_completion_period(void) { int shift = calc_period_shift(); + + if (shift > PROP_MAX_SHIFT) + shift = PROP_MAX_SHIFT; + + if (shift <= vm_completions.pg[0].shift && + shift > vm_completions.pg[0].shift / 4) + return; + prop_change_shift(&vm_completions, shift); prop_change_shift(&vm_dirties, shift); } @@ -180,7 +183,6 @@ int dirty_ratio_handler(struct ctl_table ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret == 0 && write && vm_dirty_ratio != old_ratio) { - update_completion_period(); vm_dirty_bytes = 0; } return ret; @@ -196,7 +198,6 @@ int dirty_bytes_handler(struct ctl_table ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); if (ret == 0 && write && vm_dirty_bytes != old_bytes) { - update_completion_period(); vm_dirty_ratio = 0; } return ret; @@ -1044,6 +1045,8 @@ snapshot: bdi->bw_time_stamp = now; unlock: spin_unlock(&dirty_lock); + if (gbdi->bw_time_stamp == now) + update_completion_period(); } static unsigned long max_pause(struct backing_dev_info *bdi,