block: keep q_usage_counter in atomic mode after del_gendisk

Don't switch back to percpu mode to avoid the double RCU grace period
when tearing down SCSI devices. After removing the disk only passthrough
commands can be send anyway.

Suggested-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Tested-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20210929071241.934472-6-hch@lst.de
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by Christoph Hellwig and committed by Jens Axboe aec89dc5 8e141f9e

+11 -2
+8 -1
block/blk-mq.c
··· 188 188 } 189 189 EXPORT_SYMBOL_GPL(blk_mq_freeze_queue); 190 190 191 - void blk_mq_unfreeze_queue(struct request_queue *q) 191 + void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic) 192 192 { 193 193 mutex_lock(&q->mq_freeze_lock); 194 + if (force_atomic) 195 + q->q_usage_counter.data->force_atomic = true; 194 196 q->mq_freeze_depth--; 195 197 WARN_ON_ONCE(q->mq_freeze_depth < 0); 196 198 if (!q->mq_freeze_depth) { ··· 200 198 wake_up_all(&q->mq_freeze_wq); 201 199 } 202 200 mutex_unlock(&q->mq_freeze_lock); 201 + } 202 + 203 + void blk_mq_unfreeze_queue(struct request_queue *q) 204 + { 205 + __blk_mq_unfreeze_queue(q, false); 203 206 } 204 207 EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); 205 208
+1
block/blk.h
··· 51 51 void blk_free_flush_queue(struct blk_flush_queue *q); 52 52 53 53 void blk_freeze_queue(struct request_queue *q); 54 + void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic); 54 55 void blk_queue_start_drain(struct request_queue *q); 55 56 56 57 #define BIO_INLINE_VECS 4
+2 -1
block/genhd.c
··· 596 596 /* 597 597 * Allow using passthrough request again after the queue is torn down. 598 598 */ 599 - blk_mq_unfreeze_queue(q); 599 + blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q); 600 + __blk_mq_unfreeze_queue(q, true); 600 601 601 602 if (!(disk->flags & GENHD_FL_HIDDEN)) { 602 603 sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");