aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page-writeback.c
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2010-12-16 23:22:00 -0500
committerWu Fengguang <fengguang.wu@intel.com>2011-06-07 20:25:22 -0400
commit3efaf0faba6793cd91298c76315e15de59c13ae0 (patch)
tree76712999b686348798cd21964dfba18f66854379 /mm/page-writeback.c
parent6f7186562771ec9b629914df328048449ccddf4a (diff)
writeback: skip balance_dirty_pages() for in-memory fs
This avoids unnecessary checks and dirty throttling on tmpfs/ramfs. Notes about the tmpfs/ramfs behavior changes: As for 2.6.36 and older kernels, the tmpfs writes will sleep inside balance_dirty_pages() as long as we are over the (dirty+background)/2 global throttle threshold. This is because both the dirty pages and threshold will be 0 for tmpfs/ramfs. Hence this test will always evaluate to TRUE: dirty_exceeded = (bdi_nr_reclaimable + bdi_nr_writeback >= bdi_thresh) || (nr_reclaimable + nr_writeback >= dirty_thresh); For 2.6.37, someone complained that the current logic does not allow the users to set vm.dirty_ratio=0. So commit 4cbec4c8b9 changed the test to dirty_exceeded = (bdi_nr_reclaimable + bdi_nr_writeback > bdi_thresh) || (nr_reclaimable + nr_writeback > dirty_thresh); So 2.6.37 will behave differently for tmpfs/ramfs: it will never get throttled unless the global dirty threshold is exceeded (which is very unlikely to happen; once happen, will block many tasks). I'd say that the 2.6.36 behavior is very bad for tmpfs/ramfs. It means for a busy writing server, tmpfs write()s may get livelocked! The "inadvertent" throttling can hardly bring help to any workload because of its "either no throttling, or get throttled to death" property. So based on 2.6.37, this patch won't bring more noticeable changes. CC: Hugh Dickins <hughd@google.com> Acked-by: Rik van Riel <riel@redhat.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r--mm/page-writeback.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index b8be62381396..b2529f8f8be0 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -244,13 +244,8 @@ void task_dirty_inc(struct task_struct *tsk)
244static void bdi_writeout_fraction(struct backing_dev_info *bdi, 244static void bdi_writeout_fraction(struct backing_dev_info *bdi,
245 long *numerator, long *denominator) 245 long *numerator, long *denominator)
246{ 246{
247 if (bdi_cap_writeback_dirty(bdi)) { 247 prop_fraction_percpu(&vm_completions, &bdi->completions,
248 prop_fraction_percpu(&vm_completions, &bdi->completions,
249 numerator, denominator); 248 numerator, denominator);
250 } else {
251 *numerator = 0;
252 *denominator = 1;
253 }
254} 249}
255 250
256static inline void task_dirties_fraction(struct task_struct *tsk, 251static inline void task_dirties_fraction(struct task_struct *tsk,
@@ -495,6 +490,9 @@ static void balance_dirty_pages(struct address_space *mapping,
495 bool dirty_exceeded = false; 490 bool dirty_exceeded = false;
496 struct backing_dev_info *bdi = mapping->backing_dev_info; 491 struct backing_dev_info *bdi = mapping->backing_dev_info;
497 492
493 if (!bdi_cap_account_dirty(bdi))
494 return;
495
498 for (;;) { 496 for (;;) {
499 struct writeback_control wbc = { 497 struct writeback_control wbc = {
500 .sync_mode = WB_SYNC_NONE, 498 .sync_mode = WB_SYNC_NONE,