From: Tang Junhui <tang.junhui@xxxxxxxxxx> When there is not enough dirty data in writeback cache, writeback rate is at minimum 1 key per second util all dirty data to be cleaned, it is inefficiency, and also causes waste of energy; in this patch, When there is not enough dirty data, let the writeback rate to be 0, and writeback re-schedule in bch_writeback_thread() periodically with schedule_timeout(), the behaviors are as follows : 1) If no dirty data have been read into dc->writeback_keys, goto step 2), otherwise keep writing these dirty data to back-end device at 1 key per second, until all these dirty data write over, then goto step 2). 2) Loop in bch_writeback_thread() to check if there is enough dirty data for writeback. if there is not enough diry data for writing, then sleep 10 seconds, otherwise, write dirty data to back-end device. Signed-off-by: Tang Junhui <tang.junhui@xxxxxxxxxx> --- drivers/md/bcache/util.c | 9 ++++++++- drivers/md/bcache/writeback.c | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c index dde6172..d398f09 100644 --- a/drivers/md/bcache/util.c +++ b/drivers/md/bcache/util.c @@ -209,7 +209,14 @@ uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done) { uint64_t now = local_clock(); - d->next += div_u64(done * NSEC_PER_SEC, d->rate); + /* + if d->rate is zero, write the left dirty data + at the speed of one key per second + */ + if(!d->rate) + d->next = now + NSEC_PER_SEC; + else + d->next += div_u64(done * NSEC_PER_SEC, d->rate); if (time_before64(now + NSEC_PER_SEC, d->next)) d->next = now + NSEC_PER_SEC; diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 69e1ae5..29572f7 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -15,6 +15,8 @@ #include <linux/kthread.h> #include <trace/events/bcache.h> +#define WRITE_BACK_WAIT_CYCLE 10 * HZ + /* Rate limiting */ static void __update_writeback_rate(struct cached_dev *dc) @@ -60,7 +62,7 @@ static void __update_writeback_rate(struct cached_dev *dc) dc->writeback_rate.rate = clamp_t(int64_t, (int64_t) dc->writeback_rate.rate + change, - 1, NSEC_PER_MSEC); + 0, NSEC_PER_MSEC); dc->writeback_rate_proportional = proportional; dc->writeback_rate_derivative = derivative; @@ -419,6 +421,7 @@ static int bch_writeback_thread(void *arg) while (!kthread_should_stop()) { down_write(&dc->writeback_lock); if (!atomic_read(&dc->has_dirty) || + !dc->writeback_rate.rate || (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) && !dc->writeback_running)) { up_write(&dc->writeback_lock); @@ -427,7 +430,7 @@ static int bch_writeback_thread(void *arg) if (kthread_should_stop()) return 0; - schedule(); + schedule_timeout(WRITE_BACK_WAIT_CYCLE); continue; } -- 2.8.1.windows.1 -- To unsubscribe from this list: send the line "unsubscribe linux-bcache" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html