--- /dev/null
+From 65de03e251382306a4575b1779c57c87889eee49 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 8 Nov 2019 12:18:29 -0800
+Subject: cgroup,writeback: don't switch wbs immediately on dead wbs if the memcg is dead
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 65de03e251382306a4575b1779c57c87889eee49 upstream.
+
+cgroup writeback tries to refresh the associated wb immediately if the
+current wb is dead. This is to avoid keeping issuing IOs on the stale
+wb after memcg - blkcg association has changed (ie. when blkcg got
+disabled / enabled higher up in the hierarchy).
+
+Unfortunately, the logic gets triggered spuriously on inodes which are
+associated with dead cgroups. When the logic is triggered on dead
+cgroups, the attempt fails only after doing quite a bit of work
+allocating and initializing a new wb.
+
+While c3aab9a0bd91 ("mm/filemap.c: don't initiate writeback if mapping
+has no dirty pages") alleviated the issue significantly as it now only
+triggers when the inode has dirty pages. However, the condition can
+still be triggered before the inode is switched to a different cgroup
+and the logic simply doesn't make sense.
+
+Skip the immediate switching if the associated memcg is dying.
+
+This is a simplified version of the following two patches:
+
+ * https://lore.kernel.org/linux-mm/20190513183053.GA73423@dennisz-mbp/
+ * http://lkml.kernel.org/r/156355839560.2063.5265687291430814589.stgit@buzz
+
+Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Fixes: e8a7abf5a5bd ("writeback: disassociate inodes from dying bdi_writebacks")
+Acked-by: Dennis Zhou <dennis@kernel.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -577,10 +577,13 @@ void wbc_attach_and_unlock_inode(struct
+ spin_unlock(&inode->i_lock);
+
+ /*
+- * A dying wb indicates that the memcg-blkcg mapping has changed
+- * and a new wb is already serving the memcg. Switch immediately.
++ * A dying wb indicates that either the blkcg associated with the
++ * memcg changed or the associated memcg is dying. In the first
++ * case, a replacement wb should already be available and we should
++ * refresh the wb immediately. In the second case, trying to
++ * refresh will keep failing.
+ */
+- if (unlikely(wb_dying(wbc->wb)))
++ if (unlikely(wb_dying(wbc->wb) && !css_is_dying(wbc->wb->memcg_css)))
+ inode_switch_wbs(inode, wbc->wb_id);
+ }
+ EXPORT_SYMBOL_GPL(wbc_attach_and_unlock_inode);
--- /dev/null
+From c3aab9a0bd91b696a852169479b7db1ece6cbf8c Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Date: Mon, 23 Sep 2019 15:34:45 -0700
+Subject: mm/filemap.c: don't initiate writeback if mapping has no dirty pages
+
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+
+commit c3aab9a0bd91b696a852169479b7db1ece6cbf8c upstream.
+
+Functions like filemap_write_and_wait_range() should do nothing if inode
+has no dirty pages or pages currently under writeback. But they anyway
+construct struct writeback_control and this does some atomic operations if
+CONFIG_CGROUP_WRITEBACK=y - on fast path it locks inode->i_lock and
+updates state of writeback ownership, on slow path might be more work.
+Current this path is safely avoided only when inode mapping has no pages.
+
+For example generic_file_read_iter() calls filemap_write_and_wait_range()
+at each O_DIRECT read - pretty hot path.
+
+This patch skips starting new writeback if mapping has no dirty tags set.
+If writeback is already in progress filemap_write_and_wait_range() will
+wait for it.
+
+Link: http://lkml.kernel.org/r/156378816804.1087.8607636317907921438.stgit@buzz
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/filemap.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -408,7 +408,8 @@ int __filemap_fdatawrite_range(struct ad
+ .range_end = end,
+ };
+
+- if (!mapping_cap_writeback_dirty(mapping))
++ if (!mapping_cap_writeback_dirty(mapping) ||
++ !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+ return 0;
+
+ wbc_attach_fdatawrite_inode(&wbc, mapping->host);