Linux – is `sync + drop_caches` not dropping caches

benchmarkcachelinux-kernelperformance

I have a test case for journalctl where it spends several seconds reading from the disk. But if I try to benchmark multiple runs of the test case, I find that it's impossibly fast after the first run. Even if I try to drop caches. Why?

$ sync && echo 1 | sudo tee /proc/sys/vm/drop_caches && /usr/bin/time journalctl -b -u dev-shm.mount
1
0.01user 0.03system 0:04.50elapsed 1%CPU (0avgtext+0avgdata 30956maxresident)k
95424inputs+0outputs (424major+665minor)pagefaults 0swaps
$ sync && echo 1 | sudo tee /proc/sys/vm/drop_caches && /usr/bin/time journalctl -b -u dev-shm.mount >/dev/null
1
0.00user 0.01system 0:00.08elapsed 26%CPU (0avgtext+0avgdata 31832maxresident)k
94992inputs+0outputs (422major+445minor)pagefaults 0swaps

Interestingly time still shows it doing lots of IO through page faults (inputs). I notice that if I skip the drop_caches between runs, it shows 0 instead.

Best Answer

drop_caches only affects the kernel filesystem cache. It does not affect caches in the underlying hardware. Apparently your hardware has hundreds of megabytes of cache (94992 * 4096 ~= 400MB). Awesome!

In my case, it is because the kernel is running in a VM. So the "underlying hardware" is not a simple hard disk. This illustrates the disk settings used by virt-manager.


The option used for "caching mode" respects write flushes (using fsync()), but otherwise allows caching both writes and reads in the host kernel's page cache. The "underlying hardware" effectively includes a disk cache within the the host's RAM, potentially growing to multiple gigabytes.

libvirt / KVM calls this "writeback" caching.

I've also noticed that this speeds up rebooting the VM.

Related Question