xfs
[Top] [All Lists]

Re: generic/04[89] fail on XFS due to change in writeback code [4.2-rc1

To: Eryu Guan <eguan@xxxxxxxxxx>
Subject: Re: generic/04[89] fail on XFS due to change in writeback code [4.2-rc1 regression]
From: Tejun Heo <tj@xxxxxxxxxx>
Date: Thu, 13 Aug 2015 19:24:00 -0400
Cc: Dave Chinner <david@xxxxxxxxxxxxx>, xfs@xxxxxxxxxxx, axboe@xxxxxx, jack@xxxxxxx, linux-fsdevel@xxxxxxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=ZyRk4n/NBc2/Ok5TEWkbhCRiWgiMiinigRR+o7RcD+s=; b=CHb9eUn8KqdfyEMHzmVWfAg7v4sn3jT114K56CCu+rUJiB6j/DqsuE3zm81HC7gwm0 tUkuQFsuArhv+vIqN9WgnFf96i7RSTgmpRL3JxW1hgqy1eXDIPMjHseGYuHKUaVmawdK MrIaQKdGg69H3SNVXisu5QAbF7muhw3s47fB9TsVstGUfR2mosPJJkACQ1pZBj1uwe4M 1iO5g9CO7lt/0ri2D+sbNECgcnfmWWDe9HXsXcYzDVn5d/KGtNP/b1KrCV6Wd7Vwlpsn GFwmcAHUK5kDtz23jlmll2grgdBCGet3Z8NhPQ16H3TirGooCrtp3O+Kko6pCK7i5bzG 6kmA==
In-reply-to: <20150813004435.GN3902@dastard>
References: <20150812101204.GE17933@xxxxxxxxxxxxxxxxxxxxxxxxxx> <20150813004435.GN3902@dastard>
Sender: Tejun Heo <htejun@xxxxxxxxx>
User-agent: Mutt/1.5.23 (2014-03-12)
Hello, Eryu.

Can you please do the followings?

1. See if the "writeback: fix syncing of I_DIRTY_TIME inodes" patch
   changes anything.

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?

Thanks a lot.

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,

<Prev in Thread] Current Thread [Next in Thread>