]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fs: don't flush in-flight wb switches for superblocks without cgroup writeback
authorHaifeng Xu <haifeng.xu@shopee.com>
Fri, 26 Jul 2024 03:05:25 +0000 (11:05 +0800)
committerChristian Brauner <brauner@kernel.org>
Mon, 19 Aug 2024 11:45:02 +0000 (13:45 +0200)
When deactivating any type of superblock, it had to wait for the in-flight
wb switches to be completed. wb switches are executed in inode_switch_wbs_work_fn()
which needs to acquire the wb_switch_rwsem and races against sync_inodes_sb().
If there are too much dirty data in the superblock, the waiting time may increase
significantly.

For superblocks without cgroup writeback such as tmpfs, they have nothing to
do with the wb swithes, so the flushing can be avoided.

Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com>
Link: https://lore.kernel.org/r/20240726030525.180330-1-haifeng.xu@shopee.com
Reviewed-by: Jan Kara <jack@suse.cz>
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/fs-writeback.c
fs/super.c
include/linux/writeback.h

index b865a3fa52f33648af46e70411a881ec9da4bb71..4451ecff37c4461ef8dc3a74ee5affbedf6ca0e2 100644 (file)
@@ -1132,6 +1132,7 @@ out_bdi_put:
 
 /**
  * cgroup_writeback_umount - flush inode wb switches for umount
+ * @sb: target super_block
  *
  * This function is called when a super_block is about to be destroyed and
  * flushes in-flight inode wb switches.  An inode wb switch goes through
@@ -1140,8 +1141,12 @@ out_bdi_put:
  * rare occurrences and synchronize_rcu() can take a while, perform
  * flushing iff wb switches are in flight.
  */
-void cgroup_writeback_umount(void)
+void cgroup_writeback_umount(struct super_block *sb)
 {
+
+       if (!(sb->s_bdi->capabilities & BDI_CAP_WRITEBACK))
+               return;
+
        /*
         * SB_ACTIVE should be reliably cleared before checking
         * isw_nr_in_flight, see generic_shutdown_super().
index 38d72a3cf6fcf88560f13faae8c2452de1fbad8c..28f42502bdf973824493670fbee078ab3d27b804 100644 (file)
@@ -621,7 +621,7 @@ void generic_shutdown_super(struct super_block *sb)
                sync_filesystem(sb);
                sb->s_flags &= ~SB_ACTIVE;
 
-               cgroup_writeback_umount();
+               cgroup_writeback_umount(sb);
 
                /* Evict all inodes with zero refcount. */
                evict_inodes(sb);
index 1a54676d843abe86bf81d56caf242e4a0253e209..56b85841ae4c11ac25cb7164192c94320172e103 100644 (file)
@@ -217,7 +217,7 @@ void wbc_account_cgroup_owner(struct writeback_control *wbc, struct page *page,
                              size_t bytes);
 int cgroup_writeback_by_id(u64 bdi_id, int memcg_id,
                           enum wb_reason reason, struct wb_completion *done);
-void cgroup_writeback_umount(void);
+void cgroup_writeback_umount(struct super_block *sb);
 bool cleanup_offline_cgwb(struct bdi_writeback *wb);
 
 /**
@@ -324,7 +324,7 @@ static inline void wbc_account_cgroup_owner(struct writeback_control *wbc,
 {
 }
 
-static inline void cgroup_writeback_umount(void)
+static inline void cgroup_writeback_umount(struct super_block *sb)
 {
 }