block: avoid redundant flushes for O_DSYNC direct writes - #1144
block: avoid redundant flushes for O_DSYNC direct writes#1144blktests-ci-kpd[bot] wants to merge 2 commits into
Conversation
|
Upstream branch: 3aa1dca |
|
Upstream branch: 3aa1dca |
404d204 to
88ae9d0
Compare
d89ab11 to
fdba928
Compare
|
Upstream branch: fd923b3 |
88ae9d0 to
2cd6e62
Compare
|
Upstream branch: fd923b3 |
2cd6e62 to
ed1590d
Compare
fdba928 to
60442a3
Compare
|
Upstream branch: 8d3ae59 |
ed1590d to
a7a20a9
Compare
60442a3 to
3df366e
Compare
|
Upstream branch: bd5f485 |
a7a20a9 to
2c168b9
Compare
3df366e to
5dd70cb
Compare
|
Upstream branch: 66498c7 |
2c168b9 to
06d03c0
Compare
5dd70cb to
055a766
Compare
|
Upstream branch: 502d457 |
06d03c0 to
e8c2971
Compare
055a766 to
341ae8c
Compare
|
Upstream branch: cf72cbb |
e8c2971 to
29c5a09
Compare
341ae8c to
940e422
Compare
|
Upstream branch: cee9395 |
29c5a09 to
106abfa
Compare
|
Upstream branch: 89a3129 |
106abfa to
f52267f
Compare
3cab524 to
8242bf1
Compare
|
Upstream branch: bc35965 |
f52267f to
0c9d29f
Compare
8242bf1 to
5b28f57
Compare
|
Upstream branch: df29080 Pull request is NOT updated. Failed to apply https://patchwork.kernel.org/series/1146443/ conflict: |
5b28f57 to
4ddd216
Compare
|
Upstream branch: 28924df |
0c9d29f to
b614235
Compare
4ddd216 to
00cc4ca
Compare
|
Upstream branch: 893e117 |
b614235 to
fa5d400
Compare
00cc4ca to
7efd8cd
Compare
|
Upstream branch: 50d05c7 |
fa5d400 to
17d26ef
Compare
7efd8cd to
a0aeca9
Compare
|
Upstream branch: 5225b8e |
17d26ef to
afd8108
Compare
a0aeca9 to
772381e
Compare
|
Upstream branch: 2f0c1cf |
afd8108 to
6f07d31
Compare
772381e to
0224dee
Compare
For an O_DIRECT | O_DSYNC write, dio_bio_write_op() adds REQ_FUA to the
bio, so the data is durable once the direct I/O returns. The
unconditional generic_write_sync() in blkdev_write_iter() then issues a
REQ_PREFLUSH that is redundant.
Skip it when the direct path already provided durability via FUA. A
need_sync flag, clear by default, is set only for buffered writes and
for the buffered fallback after a partial direct write.
Measured on a Seagate ST20000NM007D (20 TB, 7200 rpm, fua=1,
write_cache=write back), Linux v7.2.0-rc7, single-threaded pwrite()
loop opening the raw block device with O_WRONLY | O_DIRECT | O_DSYNC,
4 KiB writes for 60 s:
Sequential 4 KiB writes:
baseline patched
IOPS 119.7 7497.0
avg latency (us) 8357 133
p50 latency (us) 8346 127
p99 latency (us) 8368 395
p99.9 latency (us) 8728 569
Random 4 KiB writes (100 GiB span):
baseline patched
IOPS 156.1 666.4
avg latency (us) 6405 1500
p50 latency (us) 6186 1450
p99 latency (us) 16133 2285
p99.9 latency (us) 17250 9916
Signed-off-by: Zhenxian Ma <mzx199711@gmail.com>
Signed-off-by: Zhenxian Ma <mazhenxian@xiaohongshu.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
When a block device does not support FUA natively, the block layer emulates it by adding a cache flush to every write bio. An O_DSYNC direct write that spans N bios then costs N flushes, rather than the single generic_write_sync() issued after the write completes. Introduce blkdev_dio_fua() to decide when REQ_FUA is set. A synchronous write can rely on generic_write_sync() when the device lacks FUA, so it sets REQ_FUA only when bdev_fua() is true. An asynchronous write completes in blkdev_bio_end_io() and cannot call the blocking generic_write_sync(), so it keeps REQ_FUA (emulated when needed) to stay durable. Suggested-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Zhenxian Ma <mzx199711@gmail.com> Signed-off-by: Zhenxian Ma <mazhenxian@xiaohongshu.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
|
Upstream branch: 2f0c1cf |
6f07d31 to
6af0cf9
Compare
Pull request for series with
subject: block: avoid redundant flushes for O_DSYNC direct writes
version: 2
url: https://patchwork.kernel.org/project/linux-block/list/?series=1146443