diff mbox series

fs: don't flush in-flight wb switches for superblocks without cgroup writeback

Message ID 20240725023958.370787-1-haifeng.xu@shopee.com (mailing list archive)
State New
Headers show
Series fs: don't flush in-flight wb switches for superblocks without cgroup writeback | expand

Commit Message

Haifeng Xu July 25, 2024, 2:39 a.m. UTC
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>
---
 fs/super.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Jan Kara July 25, 2024, 8:42 a.m. UTC | #1
On Thu 25-07-24 10:39:58, Haifeng Xu wrote:
> 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>
> ---
>  fs/super.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/super.c b/fs/super.c
> index 095ba793e10c..f846f853e957 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -621,7 +621,8 @@ void generic_shutdown_super(struct super_block *sb)
>  		sync_filesystem(sb);
>  		sb->s_flags &= ~SB_ACTIVE;
>  
> -		cgroup_writeback_umount();
> +		if (sb->s_bdi != &noop_backing_dev_info)
> +			cgroup_writeback_umount();

So a more obvious check would be:

		if (sb->s_bdi->capabilities & BDI_CAP_WRITEBACK)

even better would be if we'd pass 'sb' into cgroup_writeback_umount() and
that function would do this check inside so that callers don't have to
bother... I know there is only one caller so this is not a huge deal but
still I'd find it cleaner that way.

								Honza
Haifeng Xu July 26, 2024, 1:55 a.m. UTC | #2
On 2024/7/25 16:42, Jan Kara wrote:
> On Thu 25-07-24 10:39:58, Haifeng Xu wrote:
>> 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>
>> ---
>>  fs/super.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/super.c b/fs/super.c
>> index 095ba793e10c..f846f853e957 100644
>> --- a/fs/super.c
>> +++ b/fs/super.c
>> @@ -621,7 +621,8 @@ void generic_shutdown_super(struct super_block *sb)
>>  		sync_filesystem(sb);
>>  		sb->s_flags &= ~SB_ACTIVE;
>>  
>> -		cgroup_writeback_umount();
>> +		if (sb->s_bdi != &noop_backing_dev_info)
>> +			cgroup_writeback_umount();
> 
> So a more obvious check would be:
> 
> 		if (sb->s_bdi->capabilities & BDI_CAP_WRITEBACK)
> 
> even better would be if we'd pass 'sb' into cgroup_writeback_umount() and
> that function would do this check inside so that callers don't have to
> bother... I know there is only one caller so this is not a huge deal but
> still I'd find it cleaner that way.
> 
> 								Honza
> 

Yes, Thanks for you suggestions!
diff mbox series

Patch

diff --git a/fs/super.c b/fs/super.c
index 095ba793e10c..f846f853e957 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -621,7 +621,8 @@  void generic_shutdown_super(struct super_block *sb)
 		sync_filesystem(sb);
 		sb->s_flags &= ~SB_ACTIVE;
 
-		cgroup_writeback_umount();
+		if (sb->s_bdi != &noop_backing_dev_info)
+			cgroup_writeback_umount();
 
 		/* Evict all inodes with zero refcount. */
 		evict_inodes(sb);