Skip to content

Commit

Permalink
block: don't try to throttle split bio if iops limit isn't set
Browse files Browse the repository at this point in the history
We need to throttle split bio in case of IOPS limit even though the
split bio has been marked as BIO_THROTTLED since block layer
accounts split bio actually.

If only throughput throttle is setup, no need to throttle any more
if BIO_THROTTLED is set since we have accounted & considered the
whole bio bytes already.

Add one flag of THROTL_TG_HAS_IOPS_LIMIT for serving this purpose.

Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20220216044514.2903784-8-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Ming Lei authored and Jens Axboe committed Feb 17, 2022
1 parent 9f5ede3 commit 5a93b60
Showing 2 changed files with 25 additions and 7 deletions.
21 changes: 14 additions & 7 deletions block/blk-throttle.c
Original file line number Diff line number Diff line change
@@ -41,11 +41,6 @@
/* A workqueue to queue throttle related work */
static struct workqueue_struct *kthrotld_workqueue;

enum tg_state_flags {
THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */
THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */
};

#define rb_entry_tg(node) rb_entry((node), struct throtl_grp, rb_node)

/* We measure latency for request size from <= 4k to >= 1M */
@@ -425,12 +420,24 @@ static void tg_update_has_rules(struct throtl_grp *tg)
struct throtl_grp *parent_tg = sq_to_tg(tg->service_queue.parent_sq);
struct throtl_data *td = tg->td;
int rw;
int has_iops_limit = 0;

for (rw = READ; rw <= WRITE; rw++) {
unsigned int iops_limit = tg_iops_limit(tg, rw);

for (rw = READ; rw <= WRITE; rw++)
tg->has_rules[rw] = (parent_tg && parent_tg->has_rules[rw]) ||
(td->limit_valid[td->limit_index] &&
(tg_bps_limit(tg, rw) != U64_MAX ||
tg_iops_limit(tg, rw) != UINT_MAX));
iops_limit != UINT_MAX));

if (iops_limit != UINT_MAX)
has_iops_limit = 1;
}

if (has_iops_limit)
tg->flags |= THROTL_TG_HAS_IOPS_LIMIT;
else
tg->flags &= ~THROTL_TG_HAS_IOPS_LIMIT;
}

static void throtl_pd_online(struct blkg_policy_data *pd)
11 changes: 11 additions & 0 deletions block/blk-throttle.h
Original file line number Diff line number Diff line change
@@ -52,6 +52,12 @@ struct throtl_service_queue {
struct timer_list pending_timer; /* fires on first_pending_disptime */
};

enum tg_state_flags {
THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */
THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */
THROTL_TG_HAS_IOPS_LIMIT = 1 << 2, /* tg has iops limit */
};

enum {
LIMIT_LOW,
LIMIT_MAX,
@@ -170,6 +176,11 @@ static inline bool blk_throtl_bio(struct bio *bio)
{
struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg);

/* no need to throttle bps any more if the bio has been throttled */
if (bio_flagged(bio, BIO_THROTTLED) &&
!(tg->flags & THROTL_TG_HAS_IOPS_LIMIT))
return false;

if (!tg->has_rules[bio_data_dir(bio)])
return false;

0 comments on commit 5a93b60

Please sign in to comment.