blk-throttle is still holding rq_qos_mutex before freezing queue from blk_throtl_init(). However blk_throtl_bio() can be called before grabbing q_usage_counter hence freeze queue really doesn't stop new IO issuing to blk-throtl. Also use READ_ONCE and WRITE_ONCE for q->td because blk_throtl_init() can concurrent with issuing IO. Signed-off-by: Yu Kuai --- block/blk-throttle.c | 11 ++--------- block/blk-throttle.h | 3 ++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 97188a795848..6c63b9714afa 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1310,7 +1310,6 @@ static int blk_throtl_init(struct gendisk *disk) { struct request_queue *q = disk->queue; struct throtl_data *td; - unsigned int memflags; int ret; td = kzalloc_node(sizeof(*td), GFP_KERNEL, q->node); @@ -1320,22 +1319,16 @@ static int blk_throtl_init(struct gendisk *disk) INIT_WORK(&td->dispatch_work, blk_throtl_dispatch_work_fn); throtl_service_queue_init(&td->service_queue); - memflags = blk_mq_freeze_queue(disk->queue); - blk_mq_quiesce_queue(disk->queue); - - q->td = td; + WRITE_ONCE(q->td, td); td->queue = q; /* activate policy, blk_throtl_activated() will return true */ ret = blkcg_activate_policy(disk, &blkcg_policy_throtl); if (ret) { - q->td = NULL; + WRITE_ONCE(q->td, NULL); kfree(td); } - blk_mq_unquiesce_queue(disk->queue); - blk_mq_unfreeze_queue(disk->queue, memflags); - return ret; } diff --git a/block/blk-throttle.h b/block/blk-throttle.h index 9d7a42c039a1..3d177b20f9e1 100644 --- a/block/blk-throttle.h +++ b/block/blk-throttle.h @@ -162,7 +162,8 @@ static inline bool blk_throtl_activated(struct request_queue *q) * blkcg_policy_enabled() guarantees that the policy is activated * in the request_queue. */ - return q->td != NULL && blkcg_policy_enabled(q, &blkcg_policy_throtl); + return READ_ONCE(q->td) && + blkcg_policy_enabled(q, &blkcg_policy_throtl); } static inline bool blk_should_throtl(struct bio *bio) -- 2.51.0