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