From: Yu Kuai <yukuai3@xxxxxxxxxx> All the caller of wbt_enable/disable_default() ensures that queue is freezed and quiesced, and it's not a good idea to enable or disable wbt while io is inflight because this will make implementation complex and easy to leak wbt inflight counter, which will cause io hang. This patch just freeze queue in wbt explicitly, there are no functional changes. Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> --- block/blk-wbt.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index b5edf44499ab..2d5a2f4ee8bc 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -729,24 +729,32 @@ void wbt_enable_default(struct gendisk *disk) { struct request_queue *q = disk->queue; struct rq_qos *rqos; - bool disable_flag = q->elevator && - test_bit(ELEVATOR_FLAG_DISABLE_WBT, &q->elevator->flags); + bool disable_flag; + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); + + disable_flag = q->elevator && test_bit(ELEVATOR_FLAG_DISABLE_WBT, + &q->elevator->flags); /* Throttling already enabled? */ rqos = wbt_rq_qos(q); if (rqos) { if (!disable_flag && RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT) RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT; - return; + goto out; } /* Queue not registered? Maybe shutting down... */ if (!blk_queue_registered(q)) - return; + goto out; if (queue_is_mq(q) && !disable_flag) wbt_init(disk); + +out: + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); } EXPORT_SYMBOL_GPL(wbt_enable_default); @@ -801,8 +809,14 @@ void wbt_disable_default(struct gendisk *disk) return; rwb = RQWB(rqos); if (rwb->enable_state == WBT_STATE_ON_DEFAULT) { + blk_mq_freeze_queue(disk->queue); + blk_mq_quiesce_queue(disk->queue); + blk_stat_deactivate(rwb->cb); rwb->enable_state = WBT_STATE_OFF_DEFAULT; + + blk_mq_unquiesce_queue(disk->queue); + blk_mq_unfreeze_queue(disk->queue); } } EXPORT_SYMBOL_GPL(wbt_disable_default); -- 2.31.1