writeback: per-task rate limit on balance_dirty_pages()
Subsystems (5)
PATCH 3/13 writeback: per-task rate limit on balance_dirty_pages()
Andrew,
References: <[email protected]>
Content-Disposition: inline; filename=writeback-per-task-dirty-count.patch
Try to limit the dirty throttle pause time in range [1 jiffy, 100 ms], by controlling how many pages can be dirtied before inserting a pause.
The dirty count will be directly billed to the task struct. Slow start and quick back off is employed, so that the stable range will be biased towards less than 50ms. Another intention is for fine timing control of slow devices, which may need to do full 100ms pauses for every 1 page.
The switch from per-cpu to per-task rate limit makes it easier to exceed the global dirty limit with a fork bomb, where each new task dirties 1 page, sleep 10m and continue to dirty 1000 more pages. The caveat is, when it dirties the first page, it may be honoured a high nr_dirtied_pause because nr_dirty is still low at that time. In this way lots of tasks get the free tickets to dirty more pages than allowed. The solution is to disable rate limiting (ie. to ignore nr_dirtied_pause) totally once the bdi becomes dirty exceeded.
Note that some filesystems will dirty a batch of pages before calling balance_dirty_pages_ratelimited_nr(). They saves a little CPU overheads at the cost of possibly overrunning the dirty limits a bit and/or in the case of very slow devices, pause the application for much more than 100ms at a time. This is a tradeoff, and seems reasonable optimization as long as the batch size is controlled within a dozen pages.
--- include/linux/sched.h | 7 ++ mm/memory_hotplug.c | 3 mm/page-writeback.c | 126 ++++++++++++++++++---------------------- 3 files changed, 65 insertions(+), 71 deletions(-)
include/linux/sched.h +7 -0
@@ -1473,6 +1473,13 @@ struct task_struct {int make_it_fail;#endif struct prop_local_single dirties; +/* +* when (nr_dirtied >= nr_dirtied_pause), it's time to call +* balance_dirty_pages() for some dirty throttling pause +*/ +int nr_dirtied; +int nr_dirtied_pause; +#ifdef CONFIG_LATENCYTOP int latency_record_count;struct latency_record latency_record[LT_SAVECOUNT ];
mm/page-writeback.c +58 -68
186 lines not on this page · raw message
mm/memory_hotplug.c +0 -3
@@ -446,8 +446,6 @@ int online_pages(unsigned long pfn, unsi vm_total_pages =nr_free_pagecache_pages (); -writeback_set_ratelimit (); -if (onlined_pages)memory_notify (MEM_ONLINE , &arg);
@@ -877,7 +875,6 @@ repeat: } vm_total_pages =nr_free_pagecache_pages (); -writeback_set_ratelimit ();memory_notify (MEM_OFFLINE , &arg);unlock_system_sleep ();
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>