aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2011-08-05 00:16:46 -0400
committerWu Fengguang <fengguang.wu@intel.com>2011-10-03 09:08:58 -0400
commit8927f66c4ede9a18b4b58f7e6f9debca67065f6b (patch)
treef7c8490ab23a20cb86874ca8112f3dd1fc6002ae /mm
parent57fc978cfb61ed40a7bbfe5a569359159ba31abd (diff)
writeback: dirty position control - bdi reserve area
Keep a minimal pool of dirty pages for each bdi, so that the disk IO queues won't underrun. Also gently increase a small bdi_thresh to avoid it stuck in 0 for some light dirtied bdi. It's particularly useful for JBOD and small memory system. It may result in (pos_ratio > 1) at the setpoint and push the dirty pages high. This is more or less intended because the bdi is in the danger of IO queue underflow. Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Diffstat (limited to 'mm')
-rw-r--r--mm/page-writeback.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 6a8bb693b42..325f753c80e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -599,6 +599,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi,
599 */ 599 */
600 if (unlikely(bdi_thresh > thresh)) 600 if (unlikely(bdi_thresh > thresh))
601 bdi_thresh = thresh; 601 bdi_thresh = thresh;
602 bdi_thresh = max(bdi_thresh, (limit - dirty) / 8);
602 /* 603 /*
603 * scale global setpoint to bdi's: 604 * scale global setpoint to bdi's:
604 * bdi_setpoint = setpoint * bdi_thresh / thresh 605 * bdi_setpoint = setpoint * bdi_thresh / thresh
@@ -622,6 +623,20 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi,
622 } else 623 } else
623 pos_ratio /= 4; 624 pos_ratio /= 4;
624 625
626 /*
627 * bdi reserve area, safeguard against dirty pool underrun and disk idle
628 * It may push the desired control point of global dirty pages higher
629 * than setpoint.
630 */
631 x_intercept = bdi_thresh / 2;
632 if (bdi_dirty < x_intercept) {
633 if (bdi_dirty > x_intercept / 8) {
634 pos_ratio *= x_intercept;
635 do_div(pos_ratio, bdi_dirty);
636 } else
637 pos_ratio *= 8;
638 }
639
625 return pos_ratio; 640 return pos_ratio;
626} 641}
627 642