block: avoid redundant flushes for O_DSYNC direct writes - #110
block: avoid redundant flushes for O_DSYNC direct writes#110blktests-ci-block-trial[bot] wants to merge 2 commits into
Conversation
|
Upstream branch: 8d3ae59 |
2225f0a to
c64cb66
Compare
|
Upstream branch: ff68e5f |
3f6c069 to
c8bcac8
Compare
c64cb66 to
f44f344
Compare
|
Upstream branch: 0f23d56 |
c8bcac8 to
c1666eb
Compare
f44f344 to
9bee990
Compare
|
Upstream branch: 1200d84 |
c1666eb to
f67acfa
Compare
9bee990 to
87a06b3
Compare
|
Upstream branch: 3a0dd7b |
f67acfa to
73f46f5
Compare
87a06b3 to
f2b91d1
Compare
|
Upstream branch: b126f6f |
73f46f5 to
aebaea8
Compare
f2b91d1 to
da1ee34
Compare
|
Upstream branch: bd5f485 |
aebaea8 to
0b91fe7
Compare
da1ee34 to
45acce2
Compare
|
Upstream branch: 59e6295 |
0b91fe7 to
438e94a
Compare
45acce2 to
c54091c
Compare
|
Upstream branch: 98f21c5 |
438e94a to
91092bb
Compare
c54091c to
f28d8dc
Compare
|
Upstream branch: cb8a75e |
91092bb to
e37edb6
Compare
f28d8dc to
3705daf
Compare
|
Upstream branch: a4ff2be |
e37edb6 to
3610377
Compare
3705daf to
98a2d8e
Compare
|
Upstream branch: 9d2ed02 |
3610377 to
c09d0db
Compare
98a2d8e to
96fc384
Compare
|
Upstream branch: c84d3e3 |
c09d0db to
e8f254c
Compare
96fc384 to
deee96f
Compare
|
Upstream branch: 77ae27f |
e8f254c to
f6d14fe
Compare
deee96f to
7d4b639
Compare
|
Upstream branch: 7f063b2 |
f6d14fe to
75457b1
Compare
7d4b639 to
e00fc7c
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: 818bebe |
75457b1 to
79c01c3
Compare
Pull request for series with
subject: block: avoid redundant flushes for O_DSYNC direct writes
version: 2
url: http://redsun45:8000/project/linux-block/list/?series=630