I have been testing Linux 4.18.16-200.fc28.x86_64
. My system has 7.7G total RAM, according to free -h
.
I have default values for the vm.dirty*
sysctl's. dirty_background_ratio
is 10, and dirty_ratio
is 20. Based on everything I've read, I expect Linux to begin writeout of dirty cache when it reaches 10% of RAM: 0.77G. And buffered write() calls should block when dirty cache reaches 20% of RAM: 1.54G.
I ran dd if=/dev/zero of=~/test bs=1M count=2000
and watched the dirty
field in atop
. While the dd
command was running, the dirty
value settled at around 0.5G. This is significantly less than the dirty background threshold (0.77G)! How can this be? What am I missing?
dirty_expire_centisecs
is 3000, so I don't think that can be the cause. I even tried lowering dirty_expire_centisecs
to 100, and dirty_writeback_centisecs
to 10, to see if that was limiting dirty
. This did not change the result.
I initially wrote these observations as part of this investigation: Why were "USB-stick stall" problems reported in 2013? Why wasn't this problem solved by the existing "No-I/O dirty throttling" code?
I understand that half-way between the two thresholds - 15% = 1.155G - write() calls start being throttled (delayed) on a curve. But no delay is added when underneath this ceiling; the processes generating dirty pages are allowed "free run".
As I understand it, the throttling aims to keep the dirty cache somewhere at or above 15%, and prevent hitting the 20% hard limit. It does not provide a guarantee for every situation. But I'm testing a simple case with one dd
command; I think it should simply ratelimit the write() calls to match the writeout speed achieved by the device.
(There is not a simple guarantee because there are some complex exceptions. For example, the throttle code limits the delay it will impose to a maximum of 200ms. But not if the target ratelimit for the process is less than one page per second; in that case it will apply a strict ratelimit.)
- Documentation/sysctl/vm.txt -- Linux v4.18
- No-I/O dirty throttling -- 2011 LWN.net.
(dirty_background_ratio + dirty_ratio)/2 dirty data in total ... is an amount of dirty data when we start to throttle processes -- Jan Kara, 2013
Users will notice that the applications will get throttled once crossing the global (background + dirty)/2=15% threshold, and then balanced around 17.5%. Before patch, the behavior is to just throttle it at 20% dirtyable memory
-- commit 143dfe8611a6, "writeback: IO-less balance_dirty_pages()"
The memory-management subsystem will, by default, try to limit dirty pages to a maximum of 15% of the memory on the system. There is a "magical function" called balance_dirty_pages() that will, if need be, throttle processes dirtying a lot of pages in order to match the rate at which pages are being dirtied and the rate at which they can be cleaned." -- Writeback and control groups, 2015 LWN.net.
- balance_dirty_pages() in Linux 4.18.16.