f2fs_write_end_io() decrements the writeback page counter and then reads it again with get_pages() to decide whether the last F2FS_WB_CP_DATA completion should wake cp_wait.
Use atomic_dec_return() for F2FS_WB_CP_DATA completions so the wakeup decision is made from the value produced by the decrement itself. Keep the existing dec_page_count() path for other writeback counters. Signed-off-by: Wenjie Qi <[email protected]> --- Changes in v3: - Drop the waitqueue protocol change from v2. - Use atomic_dec_return() directly for F2FS_WB_CP_DATA and wake cp_wait when the returned count reaches zero. fs/f2fs/data.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d83a21998ec2..58d23eb74ec2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -392,15 +392,17 @@ static void f2fs_write_end_io(struct bio *bio) if (f2fs_in_warm_node_list(folio)) f2fs_del_fsync_node_entry(sbi, folio); - dec_page_count(sbi, type); - /* * we should access sbi before folio_end_writeback() to * avoid racing w/ kill_f2fs_super() */ - if (type == F2FS_WB_CP_DATA && !get_pages(sbi, type) && - wq_has_sleeper(&sbi->cp_wait)) - wake_up(&sbi->cp_wait); + if (type == F2FS_WB_CP_DATA) { + if (!atomic_dec_return(&sbi->nr_pages[type]) && + wq_has_sleeper(&sbi->cp_wait)) + wake_up(&sbi->cp_wait); + } else { + dec_page_count(sbi, type); + } folio_clear_f2fs_gcing(folio); folio_end_writeback(folio); -- 2.43.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
