diff --git a/[refs] b/[refs] index 9a9c8d69e1e5..1763d88a3c69 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 57fc978cfb61ed40a7bbfe5a569359159ba31abd +refs/heads/master: 8927f66c4ede9a18b4b58f7e6f9debca67065f6b diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 6a8bb693b429..325f753c80ed 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -599,6 +599,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, */ if (unlikely(bdi_thresh > thresh)) bdi_thresh = thresh; + bdi_thresh = max(bdi_thresh, (limit - dirty) / 8); /* * scale global setpoint to bdi's: * bdi_setpoint = setpoint * bdi_thresh / thresh @@ -622,6 +623,20 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, } else pos_ratio /= 4; + /* + * bdi reserve area, safeguard against dirty pool underrun and disk idle + * It may push the desired control point of global dirty pages higher + * than setpoint. + */ + x_intercept = bdi_thresh / 2; + if (bdi_dirty < x_intercept) { + if (bdi_dirty > x_intercept / 8) { + pos_ratio *= x_intercept; + do_div(pos_ratio, bdi_dirty); + } else + pos_ratio *= 8; + } + return pos_ratio; }