On Thu, Aug 13, 2015 at 07:24:00PM -0400, Tejun Heo wrote: > Hello, Eryu. > > Can you please do the followings? > > 1. See if the "writeback: fix syncing of I_DIRTY_TIME inodes" patch > changes anything. After applying this patch, I can no longer reproduce the failure. > > 2. If not, apply this patch. This patch *should* make the failures go > away and might print out some error messages along with stack > trace. Can you please verify that the failures go away with this > patch and report the kernel messages if any trigger? And this patch fixed the failure too, and no WARNING no kernel message triggered. All my testings are based on 4.2-rc6 kernel (I confirmed rc6 kernel failed the test first), then applied the first patch, and reverted the first patch, and applied the second patch. > > Thanks a lot. Thanks for looking into this! Eryu > > Index: work/fs/fs-writeback.c > =================================================================== > --- work.orig/fs/fs-writeback.c > +++ work/fs/fs-writeback.c > @@ -103,7 +103,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(wbc_writepa > > static bool wb_io_lists_populated(struct bdi_writeback *wb) > { > - if (wb_has_dirty_io(wb)) { > + if (test_bit(WB_has_dirty_io, &wb->state)) { > return false; > } else { > set_bit(WB_has_dirty_io, &wb->state); > @@ -844,14 +844,13 @@ static void bdi_split_work_to_wbs(struct > struct wb_iter iter; > > might_sleep(); > - > - if (!bdi_has_dirty_io(bdi)) > - return; > restart: > rcu_read_lock(); > bdi_for_each_wb(wb, bdi, &iter, next_blkcg_id) { > - if (!wb_has_dirty_io(wb) || > - (skip_if_busy && writeback_in_progress(wb))) > + /* SYNC_ALL writes out I_DIRTY_TIME too */ > + if (!wb_has_dirty_io(wb) && base_work->sync_mode == WB_SYNC_NONE) > + continue; > + if (skip_if_busy && writeback_in_progress(wb)) > continue; > > base_work->nr_pages = wb_split_bdi_pages(wb, nr_pages); > @@ -899,8 +898,7 @@ static void bdi_split_work_to_wbs(struct > { > might_sleep(); > > - if (bdi_has_dirty_io(bdi) && > - (!skip_if_busy || !writeback_in_progress(&bdi->wb))) { > + if (!skip_if_busy || !writeback_in_progress(&bdi->wb)) { > base_work->auto_free = 0; > base_work->single_wait = 0; > base_work->single_done = 0; > @@ -2275,8 +2273,8 @@ void sync_inodes_sb(struct super_block * > }; > struct backing_dev_info *bdi = sb->s_bdi; > > - /* Nothing to do? */ > - if (!bdi_has_dirty_io(bdi) || bdi == &noop_backing_dev_info) > + /* bdi_has_dirty() ignores I_DIRTY_TIME but we can't, always kick wbs */ > + if (bdi == &noop_backing_dev_info) > return; > WARN_ON(!rwsem_is_locked(&sb->s_umount)); > > Index: work/include/linux/backing-dev.h > =================================================================== > --- work.orig/include/linux/backing-dev.h > +++ work/include/linux/backing-dev.h > @@ -38,7 +38,17 @@ extern struct workqueue_struct *bdi_wq; > > static inline bool wb_has_dirty_io(struct bdi_writeback *wb) > { > - return test_bit(WB_has_dirty_io, &wb->state); > + bool ret = test_bit(WB_has_dirty_io, &wb->state); > + > + if (!ret && (!list_empty(&wb->b_dirty) || !list_empty(&wb->b_io) || > + !list_empty(&wb->b_more_io))) { > + const char *name = wb->bdi->dev ? dev_name(wb->bdi->dev) : "UNK"; > + > + pr_err("wb_has_dirty_io: ERR %s has_dirty=%d b_dirty=%d b_io=%d b_more_io=%d\n", > + name, ret, !list_empty(&wb->b_dirty), !list_empty(&wb->b_io), !list_empty(&wb->b_more_io)); > + WARN_ON(1); > + } > + return ret; > } > > static inline bool bdi_has_dirty_io(struct backing_dev_info *bdi) > @@ -47,7 +57,18 @@ static inline bool bdi_has_dirty_io(stru > * @bdi->tot_write_bandwidth is guaranteed to be > 0 if there are > * any dirty wbs. See wb_update_write_bandwidth(). > */ > - return atomic_long_read(&bdi->tot_write_bandwidth); > + bool ret = atomic_long_read(&bdi->tot_write_bandwidth); > + > + if (ret != wb_has_dirty_io(&bdi->wb)) { > + const char *name = bdi->dev ? dev_name(bdi->dev) : "UNK"; > + > + pr_err("bdi_has_dirty_io: ERR %s tot_write_bw=%ld b_dirty=%d b_io=%d b_more_io=%d\n", > + name, atomic_long_read(&bdi->tot_write_bandwidth), > + !list_empty(&bdi->wb.b_dirty), !list_empty(&bdi->wb.b_io), !list_empty(&bdi->wb.b_more_io)); > + WARN_ON(1); > + } > + > + return ret; > } > > static inline void __add_wb_stat(struct bdi_writeback *wb, _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs