On Thu, Sep 23, 2021 at 07:27:05AM +0200, Christoph Hellwig wrote: > On Thu, Sep 23, 2021 at 09:34:03AM +0800, Ming Lei wrote: > > > + set_bit(GD_DEAD, &disk->state); > > > set_capacity(disk, 0); > > > > > > + /* > > > + * Prevent new I/O from crossing bio_queue_enter(). > > > + */ > > > + blk_queue_start_drain(q); > > > + blk_mq_freeze_queue_wait(q); > > > + > > > + rq_qos_exit(q); > > > + blk_sync_queue(q); > > > + blk_flush_integrity(); > > > + /* > > > + * Allow using passthrough request again after the queue is torn down. > > > + */ > > > + blk_mq_unfreeze_queue(q); > > > > After blk_mq_unfreeze_queue() returns, blk_try_enter_queue() will return > > true, so new FS I/O from opened bdev still won't be blocked, right? > > It won't be blocked by blk_mq_unfreeze_queue, but because the capacity > is set to 0 it still won't make it to the driver. One bio could be made & checked before set_capacity(0), then is submitted after blk_mq_unfreeze_queue() returns. blk_mq_freeze_queue_wait() doesn't always imply RCU grace period, for example, the .q_usage_counter may have been in atomic mode before calling blk_queue_start_drain() & blk_mq_freeze_queue_wait(). Thanks, Ming