After reading some articles on the Linux VFS page cache and the tunable parameters like dirty_ratio
i was under the impression that page cache would operate as both read and write caching layer.
But using the simple test below it works well to improve read speed for files that are located in the page cache but doesn't seem to work on writes.
e.g.
Clear the cache and write to file.
# swapoff -a
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/dev/zero of=/home/flo/test bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.182474 s, 172 MB/s
Check that file is actually in page cache
# vmtouch /home/flo/test
Files: 1
Directories: 0
Resident Pages: 7680/7680 30M/30M 100%
Elapsed: 0.000673 seconds
Read from file to confirm is actually coming from cache.
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.00824169 s, 3.8 GB/s
Drop cache and read again to prove speed difference.
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.132531 s, 237 MB/s
Since i'm not using DIRECT_IO with dd I was expecting the page cache to be used as a writeback type of cache. And based on dirty_ratio
or dirty_expire_centiseconds
… eventually the data would be committed to disk.
Can someone please explain how VFS handles the read and write process differently, especially during writes and why there is no speed gain.
Is there any way to make the vfs more aggressive in write caching so it behaves more like the writeback cache you might find on a raid controller for example.
Thank you
fLo
Best Answer
To see the fast behaviour, I have to do
rm test
first. E.g. I seedd
report 1GB/s instead of 150MB/s.References:
auto_da_alloc
in man ext4.Although the references only explain why I thought to try this, it doesn't actually explain why it causes the IO to block.
On my computer the blocking only seemed to happen inside the new WBT ("writeback throttling") code... which was added in 2016, after you asked your question. I haven't analyzed why it would cause this. And it went away when WBT is disabled.
My kernel version is
4.18.16-200.fc28.x86_64
.strace -T
shows that all the time was spent in close(), which makes the most sense to me. I tried to useperf
as well. It didn't work how it was supposed to, but it showed stack traces likewhich reminded me I was currently testing the
deadline
I/O scheduler, with WBT ("writeback throttling") enabled. Disabling WBT (including by switching to CFQ, which is incompatible) gave me the fast behaviour again!The
perf
commands I used to see this were: