diff options
| author | Tal Zussman <tz2294@columbia.edu> | 2026-08-10 12:39:19 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2026-08-15 17:34:19 -0600 |
| commit | 913dcbc5670cb772bddf9799d17f975e020e8326 (patch) | |
| tree | 71f479439be7f64d2adfd91a01b45783c606a497 | |
| parent | 06a2ff603f1f22dd314e24c50092717b4b8c3ade (diff) | |
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 <tz2294@columbia.edu>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260810-xfs-dontcache-double-defer-v1-1-aea7484b3e49@columbia.edu
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | fs/xfs/xfs_aops.c | 15 |
1 files 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); |
