On Thu, Apr 4, 2019 at 11:57 PM Bart Van Assche <bvanassche@xxxxxxx> wrote: > > On Thu, 2019-04-04 at 16:43 +0800, Ming Lei wrote: > > diff --git a/block/blk-mq.c b/block/blk-mq.c > > index b512ba0cb359..41c12d9008b7 100644 > > --- a/block/blk-mq.c > > +++ b/block/blk-mq.c > > @@ -3224,8 +3224,11 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, > > if (nr_hw_queues < 1 || nr_hw_queues == set->nr_hw_queues) > > return; > > > > - list_for_each_entry(q, &set->tag_list, tag_set_list) > > + list_for_each_entry(q, &set->tag_list, tag_set_list) { > > blk_mq_freeze_queue(q); > > + blk_mq_quiesce_queue(q); > > + blk_sync_queue(q); > > + } > > /* > > * Sync with blk_mq_queue_tag_busy_iter. > > */ > > @@ -3269,8 +3272,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, > > list_for_each_entry(q, &set->tag_list, tag_set_list) > > blk_mq_elv_switch_back(&head, q); > > > > - list_for_each_entry(q, &set->tag_list, tag_set_list) > > + list_for_each_entry(q, &set->tag_list, tag_set_list) { > > + blk_mq_unquiesce_queue(q); > > blk_mq_unfreeze_queue(q); > > + } > > } > > > > void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) > > Are you sure this patch is sufficient? What prevents that blk_mq_run_hw_queues() > gets called after the blk_mq_quiesce() and blk_sync_queue() calls have finished > and before the queue is unfrozen? blk_queue_quiesced(hctx->queue) is supposed to prevents blk_mq_run_hw_queues() from being called after the queue is quiesced. But there is another bug in blk_mq_quiesce() which shouldn't depend on hctx_lock(hctx, &srcu_idx) for this check, will fix blk_mq_quiesce() in V5. Thanks, Ming Lei