* [PATCH] btrfs: use IOMAP_DIO_BOUNCE flag for direct reads
@ 2026-08-28 9:28 Qu Wenruo
2026-08-28 13:26 ` Wang Yugui
0 siblings, 1 reply; 2+ messages in thread
From: Qu Wenruo @ 2026-08-28 9:28 UTC (permalink / raw)
To: linux-btrfs
Similar to direct writes, if the inode requires data checksum, we should
use a stable buffer for IO, or even for direct reads an unstable buffer
(e.g. the buffer is being modified during the direct read) can lead to
checksum mismatch and even cause read failure.
To address the potential problems of unstable dio read buffers, use
IOMAP_DIO_BOUNCE for dio reads if the inode requires data checksum.
This will bring a small performance drop, around 7% for my benchmark,
which is definitely observable on modern NVME SSDs, but the overhead is
still much smaller compared to data checksum:
Fio command line:
# fio --name=randread --filename $mnt/foobar --ioengine=libaio --size=4G \
--rw=randread --bs=64k --iodepth=64 --runtime=60 --time_based --direct=1
The VM setup:
10 vCPUs (host-passthrough), 8G RAM, target storage has cache=none
option, is backed by a cheap DRAM-less 1T mainstream PCIe4 SSD.
| Bandwidth (MiB/s) | Diff
--------------------------------+-------------------+-----------
Nodatasum, zero-copy (Baseline) | 988 | 0
Datasum, zero-copy (unpatched) | 853 | -13.7%
Datasum, bounce (patched) | 794 | -19.6%
The difference between data csum bounce and zero-copy is only 7%, which
is much more acceptable than falling back to buffered IO.
Meanwhile just enabling data checksum, even for the fastest CRC32C, the
read performance drops around 13.7%.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/direct-io.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/direct-io.c b/fs/btrfs/direct-io.c
index ed1779ccb4de..0c9386f1922b 100644
--- a/fs/btrfs/direct-io.c
+++ b/fs/btrfs/direct-io.c
@@ -818,9 +818,23 @@ static ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
size_t done_before)
{
struct btrfs_dio_data data = { 0 };
+ unsigned int dio_flags = IOMAP_DIO_PARTIAL | IOMAP_DIO_FSBLOCK_ALIGNED;
+
+ /*
+ * Data checksum requires stable buffer.
+ *
+ * And unlike dio writes, reads are always from one single
+ * mirror, so there is no need to consider mirror/parity profiles.
+ */
+ if (!(BTRFS_I(file_inode(iocb->ki_filp))->flags & BTRFS_INODE_NODATASUM)) {
+ /* Bounce will allocate memory, breaking NOWAIT. */
+ if (iocb->ki_flags & IOCB_NOWAIT)
+ return -EAGAIN;
+ dio_flags |= IOMAP_DIO_BOUNCE;
+ }
return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
- IOMAP_DIO_PARTIAL | IOMAP_DIO_FSBLOCK_ALIGNED, &data, done_before);
+ dio_flags, &data, done_before);
}
static bool need_stable_write(struct btrfs_inode *inode)
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] btrfs: use IOMAP_DIO_BOUNCE flag for direct reads
2026-08-28 9:28 [PATCH] btrfs: use IOMAP_DIO_BOUNCE flag for direct reads Qu Wenruo
@ 2026-08-28 13:26 ` Wang Yugui
0 siblings, 0 replies; 2+ messages in thread
From: Wang Yugui @ 2026-08-28 13:26 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
Hi,
> Similar to direct writes, if the inode requires data checksum, we should
> use a stable buffer for IO, or even for direct reads an unstable buffer
> (e.g. the buffer is being modified during the direct read) can lead to
> checksum mismatch and even cause read failure.
>
> To address the potential problems of unstable dio read buffers, use
> IOMAP_DIO_BOUNCE for dio reads if the inode requires data checksum.
>
> This will bring a small performance drop, around 7% for my benchmark,
> which is definitely observable on modern NVME SSDs, but the overhead is
> still much smaller compared to data checksum:
>
> Fio command line:
>
> # fio --name=randread --filename $mnt/foobar --ioengine=libaio --size=4G \
> --rw=randread --bs=64k --iodepth=64 --runtime=60 --time_based --direct=1
>
> The VM setup:
>
> 10 vCPUs (host-passthrough), 8G RAM, target storage has cache=none
> option, is backed by a cheap DRAM-less 1T mainstream PCIe4 SSD.
>
> | Bandwidth (MiB/s) | Diff
> --------------------------------+-------------------+-----------
> Nodatasum, zero-copy (Baseline) | 988 | 0
> Datasum, zero-copy (unpatched) | 853 | -13.7%
> Datasum, bounce (patched) | 794 | -19.6%
>
> The difference between data csum bounce and zero-copy is only 7%, which
> is much more acceptable than falling back to buffered IO.
for direct write, there is some process of 'falling back to buffered IO' in
btrfs_direct_write().
for direct read, there is no process of 'falling back to buffered IO' ?
Or I missed something?
Best Regards
Wang Yugui (wangyugui@e16-tech.com)
2026/08/28
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-28 13:57 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-28 9:28 [PATCH] btrfs: use IOMAP_DIO_BOUNCE flag for direct reads Qu Wenruo
2026-08-28 13:26 ` Wang Yugui
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.