Subject: writeback: control dirty pause time Date: Sat Jun 11 19:32:32 CST 2011 The dirty pause time shall ultimately be controlled by adjusting nr_dirtied_pause, since there is relationship pause = pages_dirtied / pos_bw Assuming pages_dirtied ~= nr_dirtied_pause pos_bw ~= base_bw We get nr_dirtied_pause ~= base_bw * desired_pause Here base_bw is preferred over pos_bw because it's more stable. It's also important to limit possible large transitional errors: - bw is changing quickly - pages_dirtied << nr_dirtied_pause on entering dirty exceeded area - pages_dirtied >> nr_dirtied_pause on btrfs (to be improved by a separate fix, but still expect non-trivial errors) So we end up using the above formula inside clamp_val(). The best test case for this code is to run 100 "dd bs=4M" tasks on btrfs and check its pause time distribution. Signed-off-by: Wu Fengguang --- mm/page-writeback.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) --- linux-next.orig/mm/page-writeback.c 2011-08-07 14:51:18.000000000 +0800 +++ linux-next/mm/page-writeback.c 2011-08-07 15:02:08.000000000 +0800 @@ -1021,7 +1021,19 @@ pause: bdi->dirty_exceeded = 0; current->nr_dirtied = 0; - current->nr_dirtied_pause = ratelimit_pages(nr_dirty, dirty_thresh); + if (pause == 0) + current->nr_dirtied_pause = + ratelimit_pages(nr_dirty, dirty_thresh); + else if (pause < max_pause / 4) + current->nr_dirtied_pause = clamp_val( + base_bw * (max_pause/2) / HZ, + pages_dirtied + pages_dirtied/8, + pages_dirtied * 4); + else if (pause > max_pause) + current->nr_dirtied_pause = 1 | clamp_val( + base_bw * (max_pause*3/8) / HZ, + current->nr_dirtied_pause / 4, + current->nr_dirtied_pause*7/8); if (writeback_in_progress(bdi)) return;