[PATCH] f2fs: submit cached data bios before gc_merge GC

Wenjie Qi posted 1 patch 3 days, 15 hours ago
fs/f2fs/segment.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
[PATCH] f2fs: submit cached data bios before gc_merge GC
Posted by Wenjie Qi 3 days, 15 hours ago
Commit fefdf0723650 ("f2fs: fix potential deadlock in f2fs_balance_fs()")
added cached DATA bio submission before direct foreground GC in
f2fs_balance_fs().

This avoids a deadlock between writeback and GC on cached data folios.
However, when gc_merge is enabled, f2fs_balance_fs() does not execute
foreground GC in the caller. It wakes the background GC thread and waits
for that foreground request to finish.

That branch currently skips the cached DATA bio submission, so the same
foreground GC request can still start with cached DATA bios pending.

Move the cached DATA bio submission before the gc_merge branch so both
direct and merged foreground GC paths satisfy the same precondition.

Fixes: fefdf0723650 ("f2fs: fix potential deadlock in f2fs_balance_fs()")
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
---
 fs/f2fs/segment.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 7c8ac62b1b0..1ef4edb7707 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -445,6 +445,13 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
 	if (has_enough_free_secs(sbi, 0, 0))
 		return;
 
+	/*
+	 * Submit all cached OPU/IPU DATA bios before triggering
+	 * foreground GC to avoid potential deadlocks.
+	 */
+	f2fs_submit_merged_write(sbi, DATA);
+	f2fs_submit_all_merged_ipu_writes(sbi);
+
 	if (test_opt(sbi, GC_MERGE) && sbi->gc_thread &&
 				sbi->gc_thread->f2fs_gc_task) {
 		DEFINE_WAIT(wait);
@@ -464,13 +471,6 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
 			.err_gc_skipped = false,
 			.nr_free_secs = 1 };
 
-		/*
-		 * Submit all cached OPU/IPU DATA bios before triggering
-		 * foreground GC to avoid potential deadlocks.
-		 */
-		f2fs_submit_merged_write(sbi, DATA);
-		f2fs_submit_all_merged_ipu_writes(sbi);
-
 		f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc);
 		stat_inc_gc_call_count(sbi, FOREGROUND);
 		f2fs_gc(sbi, &gc_control);
-- 
2.43.0
Re: [PATCH] f2fs: submit cached data bios before gc_merge GC
Posted by Chao Yu 3 days, 11 hours ago
I've submitted the same fix previously as below:

https://lore.kernel.org/linux-f2fs-devel/20260519011438.1168155-1-chao@kernel.org

On 5/21/26 13:30, Wenjie Qi wrote:
> Commit fefdf0723650 ("f2fs: fix potential deadlock in f2fs_balance_fs()")
> added cached DATA bio submission before direct foreground GC in
> f2fs_balance_fs().
> 
> This avoids a deadlock between writeback and GC on cached data folios.
> However, when gc_merge is enabled, f2fs_balance_fs() does not execute
> foreground GC in the caller. It wakes the background GC thread and waits
> for that foreground request to finish.
> 
> That branch currently skips the cached DATA bio submission, so the same
> foreground GC request can still start with cached DATA bios pending.
> 
> Move the cached DATA bio submission before the gc_merge branch so both
> direct and merged foreground GC paths satisfy the same precondition.
> 
> Fixes: fefdf0723650 ("f2fs: fix potential deadlock in f2fs_balance_fs()")
> Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
> ---
>   fs/f2fs/segment.c | 14 +++++++-------
>   1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 7c8ac62b1b0..1ef4edb7707 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -445,6 +445,13 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
>   	if (has_enough_free_secs(sbi, 0, 0))
>   		return;
>   
> +	/*
> +	 * Submit all cached OPU/IPU DATA bios before triggering
> +	 * foreground GC to avoid potential deadlocks.
> +	 */
> +	f2fs_submit_merged_write(sbi, DATA);
> +	f2fs_submit_all_merged_ipu_writes(sbi);
> +
>   	if (test_opt(sbi, GC_MERGE) && sbi->gc_thread &&
>   				sbi->gc_thread->f2fs_gc_task) {
>   		DEFINE_WAIT(wait);
> @@ -464,13 +471,6 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
>   			.err_gc_skipped = false,
>   			.nr_free_secs = 1 };
>   
> -		/*
> -		 * Submit all cached OPU/IPU DATA bios before triggering
> -		 * foreground GC to avoid potential deadlocks.
> -		 */
> -		f2fs_submit_merged_write(sbi, DATA);
> -		f2fs_submit_all_merged_ipu_writes(sbi);
> -
>   		f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc);
>   		stat_inc_gc_call_count(sbi, FOREGROUND);
>   		f2fs_gc(sbi, &gc_control);