balance_dirty_pages() need a reliable way to ensure some background work is scheduled for running. We cannot simply run bdi_start_writeback() because that would queue up huge number of works (which takes memory and time). CC: Jens Axboe Signed-off-by: Wu Fengguang --- fs/fs-writeback.c | 14 ++------------ include/linux/backing-dev.h | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 13 deletions(-) --- linux.orig/fs/fs-writeback.c 2009-10-06 23:38:42.000000000 +0800 +++ linux/fs/fs-writeback.c 2009-10-06 23:38:43.000000000 +0800 @@ -85,18 +85,6 @@ static inline void bdi_work_init(struct int sysctl_dirty_debug __read_mostly; -/** - * writeback_in_progress - determine whether there is writeback in progress - * @bdi: the device's backing_dev_info structure. - * - * Determine whether there is writeback waiting to be handled against a - * backing device. - */ -int writeback_in_progress(struct backing_dev_info *bdi) -{ - return !list_empty(&bdi->work_list); -} - static void bdi_work_clear(struct bdi_work *work) { clear_bit(WS_USED_B, &work->state); @@ -147,6 +135,8 @@ static void wb_clear_pending(struct bdi_ spin_lock(&bdi->wb_lock); list_del_rcu(&work->list); + if (work->args.for_background) + clear_bit(WB_FLAG_BACKGROUND_WORK, &bdi->wb_mask); spin_unlock(&bdi->wb_lock); wb_work_complete(work); --- linux.orig/include/linux/backing-dev.h 2009-10-06 23:37:47.000000000 +0800 +++ linux/include/linux/backing-dev.h 2009-10-06 23:38:43.000000000 +0800 @@ -94,6 +94,11 @@ struct backing_dev_info { #endif }; +/* + * background work queued, set to avoid redundant background works + */ +#define WB_FLAG_BACKGROUND_WORK 30 + int bdi_init(struct backing_dev_info *bdi); void bdi_destroy(struct backing_dev_info *bdi); @@ -248,7 +253,26 @@ int bdi_set_max_ratio(struct backing_dev extern struct backing_dev_info default_backing_dev_info; void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page); -int writeback_in_progress(struct backing_dev_info *bdi); +/** + * writeback_in_progress - determine whether there is writeback in progress + * @bdi: the device's backing_dev_info structure. + * + * Determine whether there is writeback waiting to be handled against a + * backing device. + */ +static inline int writeback_in_progress(struct backing_dev_info *bdi) +{ + return !list_empty(&bdi->work_list); +} + +/* + * Helper to limit # of background writeback works in circulation to 2. + * (one running and another queued) + */ +static inline int can_submit_background_writeback(struct backing_dev_info *bdi) +{ + return !test_and_set_bit(WB_FLAG_BACKGROUND_WORK, &bdi->wb_mask); +} static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits) { -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/