summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/blk-throttle.c9
-rw-r--r--include/linux/blk_types.h8
2 files changed, 15 insertions, 2 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index fea09a91c20b..ee4eeee8f21f 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -792,12 +792,16 @@ static void throtl_charge_bps_bio(struct throtl_grp *tg, struct bio *bio)
unsigned int bio_size = throtl_bio_data_size(bio);
/* Charge the bio to the group */
- if (!bio_flagged(bio, BIO_BPS_THROTTLED))
+ if (!bio_flagged(bio, BIO_BPS_THROTTLED) &&
+ !bio_flagged(bio, BIO_TG_BPS_THROTTLED)) {
+ bio_set_flag(bio, BIO_TG_BPS_THROTTLED);
tg->bytes_disp[bio_data_dir(bio)] += bio_size;
+ }
}
static void throtl_charge_iops_bio(struct throtl_grp *tg, struct bio *bio)
{
+ bio_clear_flag(bio, BIO_TG_BPS_THROTTLED);
tg->io_disp[bio_data_dir(bio)]++;
}
@@ -823,7 +827,8 @@ static unsigned long tg_dispatch_bps_time(struct throtl_grp *tg, struct bio *bio
/* no need to throttle if this bio's bytes have been accounted */
if (bps_limit == U64_MAX || tg->flags & THROTL_TG_CANCELING ||
- bio_flagged(bio, BIO_BPS_THROTTLED))
+ bio_flagged(bio, BIO_BPS_THROTTLED) ||
+ bio_flagged(bio, BIO_TG_BPS_THROTTLED))
return 0;
tg_update_slice(tg, rw);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index f38425338c3f..3d1577f07c1c 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -296,6 +296,14 @@ enum {
* of this bio. */
BIO_CGROUP_ACCT, /* has been accounted to a cgroup */
BIO_QOS_THROTTLED, /* bio went through rq_qos throttle path */
+ /*
+ * This bio has completed bps throttling at the single tg granularity,
+ * which is different from BIO_BPS_THROTTLED. When the bio is enqueued
+ * into the sq->queued of the upper tg, or is about to be dispatched,
+ * this flag needs to be cleared. Since blk-throttle and rq_qos are not
+ * on the same hierarchical level, reuse the value.
+ */
+ BIO_TG_BPS_THROTTLED = BIO_QOS_THROTTLED,
BIO_QOS_MERGED, /* but went through rq_qos merge path */
BIO_REMAPPED,
BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */