@@ -561,23 +561,16 @@ static void tg_service_queue_add(struct throtl_grp *tg)
static void throtl_enqueue_tg(struct throtl_grp *tg)
{
- if (!(tg->flags & THROTL_TG_PENDING)) {
- tg_service_queue_add(tg);
- tg->flags |= THROTL_TG_PENDING;
- tg->service_queue.parent_sq->nr_pending++;
- }
+ tg_service_queue_add(tg);
+ tg->service_queue.parent_sq->nr_pending++;
}
static void throtl_dequeue_tg(struct throtl_grp *tg)
{
- if (tg->flags & THROTL_TG_PENDING) {
- struct throtl_service_queue *parent_sq =
- tg->service_queue.parent_sq;
+ struct throtl_service_queue *parent_sq = tg->service_queue.parent_sq;
- throtl_rb_erase(&tg->rb_node, parent_sq);
- --parent_sq->nr_pending;
- tg->flags &= ~THROTL_TG_PENDING;
- }
+ throtl_rb_erase(&tg->rb_node, parent_sq);
+ --parent_sq->nr_pending;
}
/* Call with queue lock held */
@@ -1015,8 +1008,9 @@ static void throtl_add_bio_tg(struct bio *bio, struct throtl_qnode *qn,
throtl_qnode_add_bio(bio, qn, &sq->queued[rw]);
+ if (!sq->nr_queued[READ] && !sq->nr_queued[WRITE])
+ throtl_enqueue_tg(tg);
sq->nr_queued[rw]++;
- throtl_enqueue_tg(tg);
}
static void tg_update_disptime(struct throtl_grp *tg)
@@ -1371,7 +1365,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
throtl_start_new_slice(tg, READ, false);
throtl_start_new_slice(tg, WRITE, false);
- if (tg->flags & THROTL_TG_PENDING) {
+ if (sq->nr_queued[READ] || sq->nr_queued[WRITE]) {
tg_update_disptime(tg);
throtl_schedule_next_dispatch(sq->parent_sq, true);
}
@@ -53,10 +53,9 @@ struct throtl_service_queue {
};
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 */
- THROTL_TG_CANCELING = 1 << 3, /* starts to cancel bio */
+ THROTL_TG_WAS_EMPTY = 1 << 0, /* bio_lists[] became non-empty */
+ THROTL_TG_HAS_IOPS_LIMIT = 1 << 1, /* tg has iops limit */
+ THROTL_TG_CANCELING = 1 << 2, /* starts to cancel bio */
};
enum {
All related operations are inside 'queue_lock', there is no need to use the flag, we only need to make sure throtl_enqueue_tg() is called when the first bio is throttled, and throtl_dequeue_tg() is called when the last throttled bio is dispatched. Signed-off-by: Yu Kuai <yukuai3@huawei.com> --- block/blk-throttle.c | 22 ++++++++-------------- block/blk-throttle.h | 7 +++---- 2 files changed, 11 insertions(+), 18 deletions(-)