diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-06-25 09:35:01 +0200 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-06-25 12:36:33 +0200 |
commit | 3336a136d7ae49d91f4da35250feffb886f85344 (patch) | |
tree | 3829c54f9fd654f932904170d8d54c521466e051 /fs/fs-writeback.c | |
parent | f5a0e4626031b61e1ebb20b2d6c643788847aa3b (diff) |
writeback: allow sleepy exit of default writeback task
Since we do lazy create of default writeback tasks for a bdi, we can
allow sleepy exit if it has been completely idle for 5 minutes.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r-- | fs/fs-writeback.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 806948389ab2..796b24389485 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -369,7 +369,7 @@ static struct bdi_work *get_next_work_item(struct backing_dev_info *bdi, /* * Retrieve work items and do the writeback they describe */ -void wb_do_writeback(struct bdi_writeback *wb, int force_wait) +long wb_do_writeback(struct bdi_writeback *wb, int force_wait) { struct backing_dev_info *bdi = wb->bdi; struct bdi_work *work; @@ -414,8 +414,10 @@ void wb_do_writeback(struct bdi_writeback *wb, int force_wait) global_page_state(NR_UNSTABLE_NFS) + (inodes_stat.nr_inodes - inodes_stat.nr_unused); - wb_writeback(wb, nr_pages, NULL, WB_SYNC_NONE, 1); + wrote = wb_writeback(wb, nr_pages, NULL, WB_SYNC_NONE, 1); } + + return wrote; } /* @@ -424,10 +426,28 @@ void wb_do_writeback(struct bdi_writeback *wb, int force_wait) */ int bdi_writeback_task(struct bdi_writeback *wb) { + unsigned long last_active = jiffies; + unsigned long wait_jiffies = -1UL; + long pages_written; + while (!kthread_should_stop()) { - unsigned long wait_jiffies; + pages_written = wb_do_writeback(wb, 0); + + if (pages_written) + last_active = jiffies; + else if (wait_jiffies != -1UL) { + unsigned long max_idle; - wb_do_writeback(wb, 0); + /* + * Longest period of inactivity that we tolerate. If we + * see dirty data again later, the task will get + * recreated automatically. + */ + max_idle = max(5UL * 60 * HZ, wait_jiffies); + if (time_after(jiffies, max_idle + last_active) && + wb_is_default_task(wb)) + break; + } wait_jiffies = msecs_to_jiffies(dirty_writeback_interval * 10); set_current_state(TASK_INTERRUPTIBLE); |