aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page-writeback.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-05-22 18:23:26 -0400
committerJens Axboe <axboe@fb.com>2015-06-02 10:38:13 -0400
commitdaddfa3cb30ebfe322d50af146d830fd435ddb1f (patch)
tree4b67764441edb8e62798565e314759ce048218dd /mm/page-writeback.c
parentb1cbc6d40c85639d405fee37c7bb688c3bf468d6 (diff)
writeback: add dirty_throttle_control->pos_ratio
wb_position_ratio() is used to calculate pos_ratio, which is used for two purposes. wb_update_dirty_ratelimit() uses it to adjust wb->[balanced_]dirty_ratelimit gradually and balance_dirty_pages() to immediately adjust dirty_ratelimit right before applying it to determine pause duration. While wb_update_dirty_ratelimit() is separately rate limited from balance_dirty_pages(), on the run where the ratelimit is updated, we end up calculating pos_ratio twice with the same parameters. This patch adds dirty_throttle_control->pos_ratio. balance_dirty_pages() calculates it once per run and wb_update_dirty_ratelimit() uses the value stored in dirty_throttle_control. This removes the duplicate calculation and also will help implementing memcg wb_domain. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Jan Kara <jack@suse.cz> Cc: Wu Fengguang <fengguang.wu@intel.com> Cc: Greg Thelen <gthelen@google.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r--mm/page-writeback.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 2352c69bff12..fcebae7db874 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -135,6 +135,8 @@ struct dirty_throttle_control {
135 unsigned long wb_dirty; /* per-wb counterparts */ 135 unsigned long wb_dirty; /* per-wb counterparts */
136 unsigned long wb_thresh; 136 unsigned long wb_thresh;
137 unsigned long wb_bg_thresh; 137 unsigned long wb_bg_thresh;
138
139 unsigned long pos_ratio;
138}; 140};
139 141
140#define GDTC_INIT(__wb) .wb = (__wb) 142#define GDTC_INIT(__wb) .wb = (__wb)
@@ -717,7 +719,7 @@ static long long pos_ratio_polynom(unsigned long setpoint,
717 * card's wb_dirty may rush to many times higher than wb_setpoint. 719 * card's wb_dirty may rush to many times higher than wb_setpoint.
718 * - the wb dirty thresh drops quickly due to change of JBOD workload 720 * - the wb dirty thresh drops quickly due to change of JBOD workload
719 */ 721 */
720static unsigned long wb_position_ratio(struct dirty_throttle_control *dtc) 722static void wb_position_ratio(struct dirty_throttle_control *dtc)
721{ 723{
722 struct bdi_writeback *wb = dtc->wb; 724 struct bdi_writeback *wb = dtc->wb;
723 unsigned long write_bw = wb->avg_write_bandwidth; 725 unsigned long write_bw = wb->avg_write_bandwidth;
@@ -731,8 +733,10 @@ static unsigned long wb_position_ratio(struct dirty_throttle_control *dtc)
731 long long pos_ratio; /* for scaling up/down the rate limit */ 733 long long pos_ratio; /* for scaling up/down the rate limit */
732 long x; 734 long x;
733 735
736 dtc->pos_ratio = 0;
737
734 if (unlikely(dtc->dirty >= limit)) 738 if (unlikely(dtc->dirty >= limit))
735 return 0; 739 return;
736 740
737 /* 741 /*
738 * global setpoint 742 * global setpoint
@@ -770,18 +774,20 @@ static unsigned long wb_position_ratio(struct dirty_throttle_control *dtc)
770 if (unlikely(wb->bdi->capabilities & BDI_CAP_STRICTLIMIT)) { 774 if (unlikely(wb->bdi->capabilities & BDI_CAP_STRICTLIMIT)) {
771 long long wb_pos_ratio; 775 long long wb_pos_ratio;
772 776
773 if (dtc->wb_dirty < 8) 777 if (dtc->wb_dirty < 8) {
774 return min_t(long long, pos_ratio * 2, 778 dtc->pos_ratio = min_t(long long, pos_ratio * 2,
775 2 << RATELIMIT_CALC_SHIFT); 779 2 << RATELIMIT_CALC_SHIFT);
780 return;
781 }
776 782
777 if (dtc->wb_dirty >= wb_thresh) 783 if (dtc->wb_dirty >= wb_thresh)
778 return 0; 784 return;
779 785
780 wb_setpoint = dirty_freerun_ceiling(wb_thresh, 786 wb_setpoint = dirty_freerun_ceiling(wb_thresh,
781 dtc->wb_bg_thresh); 787 dtc->wb_bg_thresh);
782 788
783 if (wb_setpoint == 0 || wb_setpoint == wb_thresh) 789 if (wb_setpoint == 0 || wb_setpoint == wb_thresh)
784 return 0; 790 return;
785 791
786 wb_pos_ratio = pos_ratio_polynom(wb_setpoint, dtc->wb_dirty, 792 wb_pos_ratio = pos_ratio_polynom(wb_setpoint, dtc->wb_dirty,
787 wb_thresh); 793 wb_thresh);
@@ -807,7 +813,8 @@ static unsigned long wb_position_ratio(struct dirty_throttle_control *dtc)
807 * is 2. We might want to tweak this if we observe the control 813 * is 2. We might want to tweak this if we observe the control
808 * system is too slow to adapt. 814 * system is too slow to adapt.
809 */ 815 */
810 return min(pos_ratio, wb_pos_ratio); 816 dtc->pos_ratio = min(pos_ratio, wb_pos_ratio);
817 return;
811 } 818 }
812 819
813 /* 820 /*
@@ -888,7 +895,7 @@ static unsigned long wb_position_ratio(struct dirty_throttle_control *dtc)
888 pos_ratio *= 8; 895 pos_ratio *= 8;
889 } 896 }
890 897
891 return pos_ratio; 898 dtc->pos_ratio = pos_ratio;
892} 899}
893 900
894static void wb_update_write_bandwidth(struct bdi_writeback *wb, 901static void wb_update_write_bandwidth(struct bdi_writeback *wb,
@@ -1009,7 +1016,6 @@ static void wb_update_dirty_ratelimit(struct dirty_throttle_control *dtc,
1009 unsigned long dirty_rate; 1016 unsigned long dirty_rate;
1010 unsigned long task_ratelimit; 1017 unsigned long task_ratelimit;
1011 unsigned long balanced_dirty_ratelimit; 1018 unsigned long balanced_dirty_ratelimit;
1012 unsigned long pos_ratio;
1013 unsigned long step; 1019 unsigned long step;
1014 unsigned long x; 1020 unsigned long x;
1015 1021
@@ -1019,12 +1025,11 @@ static void wb_update_dirty_ratelimit(struct dirty_throttle_control *dtc,
1019 */ 1025 */
1020 dirty_rate = (dirtied - wb->dirtied_stamp) * HZ / elapsed; 1026 dirty_rate = (dirtied - wb->dirtied_stamp) * HZ / elapsed;
1021 1027
1022 pos_ratio = wb_position_ratio(dtc);
1023 /* 1028 /*
1024 * task_ratelimit reflects each dd's dirty rate for the past 200ms. 1029 * task_ratelimit reflects each dd's dirty rate for the past 200ms.
1025 */ 1030 */
1026 task_ratelimit = (u64)dirty_ratelimit * 1031 task_ratelimit = (u64)dirty_ratelimit *
1027 pos_ratio >> RATELIMIT_CALC_SHIFT; 1032 dtc->pos_ratio >> RATELIMIT_CALC_SHIFT;
1028 task_ratelimit++; /* it helps rampup dirty_ratelimit from tiny values */ 1033 task_ratelimit++; /* it helps rampup dirty_ratelimit from tiny values */
1029 1034
1030 /* 1035 /*
@@ -1375,7 +1380,6 @@ static void balance_dirty_pages(struct address_space *mapping,
1375 bool dirty_exceeded = false; 1380 bool dirty_exceeded = false;
1376 unsigned long task_ratelimit; 1381 unsigned long task_ratelimit;
1377 unsigned long dirty_ratelimit; 1382 unsigned long dirty_ratelimit;
1378 unsigned long pos_ratio;
1379 struct backing_dev_info *bdi = wb->bdi; 1383 struct backing_dev_info *bdi = wb->bdi;
1380 bool strictlimit = bdi->capabilities & BDI_CAP_STRICTLIMIT; 1384 bool strictlimit = bdi->capabilities & BDI_CAP_STRICTLIMIT;
1381 unsigned long start_time = jiffies; 1385 unsigned long start_time = jiffies;
@@ -1433,6 +1437,9 @@ static void balance_dirty_pages(struct address_space *mapping,
1433 1437
1434 dirty_exceeded = (gdtc->wb_dirty > gdtc->wb_thresh) && 1438 dirty_exceeded = (gdtc->wb_dirty > gdtc->wb_thresh) &&
1435 ((gdtc->dirty > gdtc->thresh) || strictlimit); 1439 ((gdtc->dirty > gdtc->thresh) || strictlimit);
1440
1441 wb_position_ratio(gdtc);
1442
1436 if (dirty_exceeded && !wb->dirty_exceeded) 1443 if (dirty_exceeded && !wb->dirty_exceeded)
1437 wb->dirty_exceeded = 1; 1444 wb->dirty_exceeded = 1;
1438 1445
@@ -1444,8 +1451,7 @@ static void balance_dirty_pages(struct address_space *mapping,
1444 } 1451 }
1445 1452
1446 dirty_ratelimit = wb->dirty_ratelimit; 1453 dirty_ratelimit = wb->dirty_ratelimit;
1447 pos_ratio = wb_position_ratio(gdtc); 1454 task_ratelimit = ((u64)dirty_ratelimit * gdtc->pos_ratio) >>
1448 task_ratelimit = ((u64)dirty_ratelimit * pos_ratio) >>
1449 RATELIMIT_CALC_SHIFT; 1455 RATELIMIT_CALC_SHIFT;
1450 max_pause = wb_max_pause(wb, gdtc->wb_dirty); 1456 max_pause = wb_max_pause(wb, gdtc->wb_dirty);
1451 min_pause = wb_min_pause(wb, max_pause, 1457 min_pause = wb_min_pause(wb, max_pause,