summaryrefslogtreecommitdiffstats
path: root/block/blk-throttle.c
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2017-03-27 13:51:42 -0400
committerJens Axboe <axboe@fb.com>2017-03-28 10:02:20 -0400
commitada75b6e5b2a939401d4919dfaf2f2fc9484f68a (patch)
tree9f07b5a5edb225e495dc6ec46b5a7e7b96182fcc /block/blk-throttle.c
parent9e234eeafbe17e85908584392f249f0b329b8e1b (diff)
blk-throttle: add interface to configure idle time threshold
Add interface to configure the threshold. The io.low interface will like: echo "8:16 rbps=2097152 wbps=max idle=2000" > io.low idle is in microsecond unit. Signed-off-by: Shaohua Li <shli@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/blk-throttle.c')
-rw-r--r--block/blk-throttle.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 6300f3ed70d2..f03e158ee197 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -181,6 +181,8 @@ struct throtl_data
181 unsigned int limit_index; 181 unsigned int limit_index;
182 bool limit_valid[LIMIT_CNT]; 182 bool limit_valid[LIMIT_CNT];
183 183
184 unsigned long dft_idletime_threshold; /* us */
185
184 unsigned long low_upgrade_time; 186 unsigned long low_upgrade_time;
185 unsigned long low_downgrade_time; 187 unsigned long low_downgrade_time;
186 188
@@ -477,10 +479,7 @@ static void throtl_pd_init(struct blkg_policy_data *pd)
477 sq->parent_sq = &blkg_to_tg(blkg->parent)->service_queue; 479 sq->parent_sq = &blkg_to_tg(blkg->parent)->service_queue;
478 tg->td = td; 480 tg->td = td;
479 481
480 if (blk_queue_nonrot(td->queue)) 482 tg->idletime_threshold = td->dft_idletime_threshold;
481 tg->idletime_threshold = DFL_IDLE_THRESHOLD_SSD;
482 else
483 tg->idletime_threshold = DFL_IDLE_THRESHOLD_HD;
484} 483}
485 484
486/* 485/*
@@ -1449,6 +1448,7 @@ static u64 tg_prfill_limit(struct seq_file *sf, struct blkg_policy_data *pd,
1449 char bufs[4][21] = { "max", "max", "max", "max" }; 1448 char bufs[4][21] = { "max", "max", "max", "max" };
1450 u64 bps_dft; 1449 u64 bps_dft;
1451 unsigned int iops_dft; 1450 unsigned int iops_dft;
1451 char idle_time[26] = "";
1452 1452
1453 if (!dname) 1453 if (!dname)
1454 return 0; 1454 return 0;
@@ -1464,7 +1464,9 @@ static u64 tg_prfill_limit(struct seq_file *sf, struct blkg_policy_data *pd,
1464 if (tg->bps_conf[READ][off] == bps_dft && 1464 if (tg->bps_conf[READ][off] == bps_dft &&
1465 tg->bps_conf[WRITE][off] == bps_dft && 1465 tg->bps_conf[WRITE][off] == bps_dft &&
1466 tg->iops_conf[READ][off] == iops_dft && 1466 tg->iops_conf[READ][off] == iops_dft &&
1467 tg->iops_conf[WRITE][off] == iops_dft) 1467 tg->iops_conf[WRITE][off] == iops_dft &&
1468 (off != LIMIT_LOW || tg->idletime_threshold ==
1469 tg->td->dft_idletime_threshold))
1468 return 0; 1470 return 0;
1469 1471
1470 if (tg->bps_conf[READ][off] != bps_dft) 1472 if (tg->bps_conf[READ][off] != bps_dft)
@@ -1479,9 +1481,16 @@ static u64 tg_prfill_limit(struct seq_file *sf, struct blkg_policy_data *pd,
1479 if (tg->iops_conf[WRITE][off] != iops_dft) 1481 if (tg->iops_conf[WRITE][off] != iops_dft)
1480 snprintf(bufs[3], sizeof(bufs[3]), "%u", 1482 snprintf(bufs[3], sizeof(bufs[3]), "%u",
1481 tg->iops_conf[WRITE][off]); 1483 tg->iops_conf[WRITE][off]);
1484 if (off == LIMIT_LOW) {
1485 if (tg->idletime_threshold == ULONG_MAX)
1486 strcpy(idle_time, " idle=max");
1487 else
1488 snprintf(idle_time, sizeof(idle_time), " idle=%lu",
1489 tg->idletime_threshold);
1490 }
1482 1491
1483 seq_printf(sf, "%s rbps=%s wbps=%s riops=%s wiops=%s\n", 1492 seq_printf(sf, "%s rbps=%s wbps=%s riops=%s wiops=%s%s\n",
1484 dname, bufs[0], bufs[1], bufs[2], bufs[3]); 1493 dname, bufs[0], bufs[1], bufs[2], bufs[3], idle_time);
1485 return 0; 1494 return 0;
1486} 1495}
1487 1496
@@ -1499,6 +1508,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
1499 struct blkg_conf_ctx ctx; 1508 struct blkg_conf_ctx ctx;
1500 struct throtl_grp *tg; 1509 struct throtl_grp *tg;
1501 u64 v[4]; 1510 u64 v[4];
1511 unsigned long idle_time;
1502 int ret; 1512 int ret;
1503 int index = of_cft(of)->private; 1513 int index = of_cft(of)->private;
1504 1514
@@ -1513,6 +1523,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
1513 v[2] = tg->iops_conf[READ][index]; 1523 v[2] = tg->iops_conf[READ][index];
1514 v[3] = tg->iops_conf[WRITE][index]; 1524 v[3] = tg->iops_conf[WRITE][index];
1515 1525
1526 idle_time = tg->idletime_threshold;
1516 while (true) { 1527 while (true) {
1517 char tok[27]; /* wiops=18446744073709551616 */ 1528 char tok[27]; /* wiops=18446744073709551616 */
1518 char *p; 1529 char *p;
@@ -1544,6 +1555,8 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
1544 v[2] = min_t(u64, val, UINT_MAX); 1555 v[2] = min_t(u64, val, UINT_MAX);
1545 else if (!strcmp(tok, "wiops")) 1556 else if (!strcmp(tok, "wiops"))
1546 v[3] = min_t(u64, val, UINT_MAX); 1557 v[3] = min_t(u64, val, UINT_MAX);
1558 else if (off == LIMIT_LOW && !strcmp(tok, "idle"))
1559 idle_time = val;
1547 else 1560 else
1548 goto out_finish; 1561 goto out_finish;
1549 } 1562 }
@@ -1572,6 +1585,8 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
1572 blk_throtl_update_limit_valid(tg->td); 1585 blk_throtl_update_limit_valid(tg->td);
1573 if (tg->td->limit_valid[LIMIT_LOW]) 1586 if (tg->td->limit_valid[LIMIT_LOW])
1574 tg->td->limit_index = LIMIT_LOW; 1587 tg->td->limit_index = LIMIT_LOW;
1588 tg->idletime_threshold = (idle_time == ULONG_MAX) ?
1589 ULONG_MAX : idle_time;
1575 } 1590 }
1576 tg_conf_updated(tg); 1591 tg_conf_updated(tg);
1577 ret = 0; 1592 ret = 0;
@@ -2122,10 +2137,13 @@ void blk_throtl_register_queue(struct request_queue *q)
2122 td = q->td; 2137 td = q->td;
2123 BUG_ON(!td); 2138 BUG_ON(!td);
2124 2139
2125 if (blk_queue_nonrot(q)) 2140 if (blk_queue_nonrot(q)) {
2126 td->throtl_slice = DFL_THROTL_SLICE_SSD; 2141 td->throtl_slice = DFL_THROTL_SLICE_SSD;
2127 else 2142 td->dft_idletime_threshold = DFL_IDLE_THRESHOLD_SSD;
2143 } else {
2128 td->throtl_slice = DFL_THROTL_SLICE_HD; 2144 td->throtl_slice = DFL_THROTL_SLICE_HD;
2145 td->dft_idletime_threshold = DFL_IDLE_THRESHOLD_HD;
2146 }
2129#ifndef CONFIG_BLK_DEV_THROTTLING_LOW 2147#ifndef CONFIG_BLK_DEV_THROTTLING_LOW
2130 /* if no low limit, use previous default */ 2148 /* if no low limit, use previous default */
2131 td->throtl_slice = DFL_THROTL_SLICE_HD; 2149 td->throtl_slice = DFL_THROTL_SLICE_HD;
@@ -2139,10 +2157,7 @@ void blk_throtl_register_queue(struct request_queue *q)
2139 blkg_for_each_descendant_post(blkg, pos_css, q->root_blkg) { 2157 blkg_for_each_descendant_post(blkg, pos_css, q->root_blkg) {
2140 struct throtl_grp *tg = blkg_to_tg(blkg); 2158 struct throtl_grp *tg = blkg_to_tg(blkg);
2141 2159
2142 if (blk_queue_nonrot(q)) 2160 tg->idletime_threshold = td->dft_idletime_threshold;
2143 tg->idletime_threshold = DFL_IDLE_THRESHOLD_SSD;
2144 else
2145 tg->idletime_threshold = DFL_IDLE_THRESHOLD_HD;
2146 } 2161 }
2147 rcu_read_unlock(); 2162 rcu_read_unlock();
2148} 2163}