From 913dcbc5670cb772bddf9799d17f975e020e8326 Mon Sep 17 00:00:00 2001 From: Tal Zussman Date: Mon, 10 Aug 2026 12:39:19 -0400 Subject: [PATCH] xfs: avoid double deferrals for RWF_DONTCACHE writes XFS already defers some writes to a workqueue when transactions are needed to process the I/O completion. Disable the block layer bio task completion in this case to avoid a major performance drop. Fixes: efbde6f9f449 ("iomap: use BIO_COMPLETE_IN_TASK for dropbehind writeback") Link: https://lore.kernel.org/all/8124341f-3af2-4a16-897d-38db5ab5a9d4@columbia.edu/ Signed-off-by: Tal Zussman Reviewed-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20260810-xfs-dontcache-double-defer-v1-1-aea7484b3e49@columbia.edu Signed-off-by: Jens Axboe --- fs/xfs/xfs_aops.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index cd8de8c82d78..74a6089abadf 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -549,10 +549,14 @@ xfs_writeback_submit( } /* - * Send ioends that might require a transaction to the completion wq. + * Send ioends that might require a transaction to the completion wq, + * and disable the block layer task completion for them as there is no + * need to defer twice. */ - if (xfs_ioend_needs_wq_completion(ioend)) + if (xfs_ioend_needs_wq_completion(ioend)) { ioend->io_bio.bi_end_io = xfs_end_bio; + bio_clear_flag(&ioend->io_bio, BIO_COMPLETE_IN_TASK); + } return iomap_ioend_writeback_submit(wpc, error); } @@ -663,7 +667,14 @@ xfs_zoned_writeback_submit( { struct iomap_ioend *ioend = wpc->wb_ctx; + /* + * Defer all completions to our workqueue as all zoned writes require a + * transaction to be persisted. This also means we never need the block + * layer in-task completion for a task context. + */ ioend->io_bio.bi_end_io = xfs_end_bio; + bio_clear_flag(&ioend->io_bio, BIO_COMPLETE_IN_TASK); + if (error) { ioend->io_bio.bi_status = errno_to_blk_status(error); bio_endio(&ioend->io_bio);