diff mbox series

[4/4] block: keep q_usage_counter in atomic mode after del_gendisk

Message ID 20210920112405.1299667-5-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [1/4] block: factor out a blk_try_enter_queue helper | expand

Commit Message

Christoph Hellwig Sept. 20, 2021, 11:24 a.m. UTC
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>
---
 block/blk-mq.c | 9 ++++++++-
 block/blk.h    | 1 +
 block/genhd.c  | 1 +
 3 files changed, 10 insertions(+), 1 deletion(-)

Comments

Bart Van Assche Sept. 21, 2021, 3:29 a.m. UTC | #1
On 9/20/21 04:24, Christoph Hellwig wrote:
> 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.
                   ^^^^
                   sent?

> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 108a352051be5..bc026372de439 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -188,9 +188,11 @@ void blk_mq_freeze_queue(struct request_queue *q)
>   }
>   EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
>   
> -void blk_mq_unfreeze_queue(struct request_queue *q)
> +void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
>   {
>   	mutex_lock(&q->mq_freeze_lock);
> +	if (force_atomic)
> +		q->q_usage_counter.data->force_atomic = true;
>   	q->mq_freeze_depth--;
>   	WARN_ON_ONCE(q->mq_freeze_depth < 0);
>   	if (!q->mq_freeze_depth) {
> @@ -199,6 +201,11 @@ void blk_mq_unfreeze_queue(struct request_queue *q)
>   	}
>   	mutex_unlock(&q->mq_freeze_lock);
>   }
> +
> +void blk_mq_unfreeze_queue(struct request_queue *q)
> +{
> +	__blk_mq_unfreeze_queue(q, false);
> +}
>   EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
>   
>   /*
> diff --git a/block/blk.h b/block/blk.h
> index e2ed2257709ae..6c3c00a8fe19d 100644
> --- a/block/blk.h
> +++ b/block/blk.h
> @@ -51,6 +51,7 @@ struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
>   void blk_free_flush_queue(struct blk_flush_queue *q);
>   
>   void blk_freeze_queue(struct request_queue *q);
> +void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
>   void blk_queue_start_drain(struct request_queue *q);
>   
>   #define BIO_INLINE_VECS 4
> diff --git a/block/genhd.c b/block/genhd.c
> index b3c33495d7208..fe23085ddddd6 100644
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -596,6 +596,7 @@ void del_gendisk(struct gendisk *disk)
>   	/*
>   	 * Allow using passthrough request again after the queue is torn down.
>   	 */
> +	blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
>   	blk_mq_unfreeze_queue(q);
>   
>   	if (!(disk->flags & GENHD_FL_HIDDEN)) {

I don't see any code that passes 'true' as second argument to
__blk_mq_unfreeze_queue()? Did I perhaps overlook something?

Thanks,

Bart.
Christoph Hellwig Sept. 21, 2021, 9:07 a.m. UTC | #2
On Mon, Sep 20, 2021 at 08:29:49PM -0700, Bart Van Assche wrote:
>>   	blk_mq_unfreeze_queue(q);
>>     	if (!(disk->flags & GENHD_FL_HIDDEN)) {
>
> I don't see any code that passes 'true' as second argument to
> __blk_mq_unfreeze_queue()? Did I perhaps overlook something?

No, I did not finish actually implementing the suggestion from
Ming properly, sorry.
diff mbox series

Patch

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 108a352051be5..bc026372de439 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -188,9 +188,11 @@  void blk_mq_freeze_queue(struct request_queue *q)
 }
 EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
 
-void blk_mq_unfreeze_queue(struct request_queue *q)
+void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
 {
 	mutex_lock(&q->mq_freeze_lock);
+	if (force_atomic)
+		q->q_usage_counter.data->force_atomic = true;
 	q->mq_freeze_depth--;
 	WARN_ON_ONCE(q->mq_freeze_depth < 0);
 	if (!q->mq_freeze_depth) {
@@ -199,6 +201,11 @@  void blk_mq_unfreeze_queue(struct request_queue *q)
 	}
 	mutex_unlock(&q->mq_freeze_lock);
 }
+
+void blk_mq_unfreeze_queue(struct request_queue *q)
+{
+	__blk_mq_unfreeze_queue(q, false);
+}
 EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
 
 /*
diff --git a/block/blk.h b/block/blk.h
index e2ed2257709ae..6c3c00a8fe19d 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -51,6 +51,7 @@  struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
 void blk_free_flush_queue(struct blk_flush_queue *q);
 
 void blk_freeze_queue(struct request_queue *q);
+void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
 void blk_queue_start_drain(struct request_queue *q);
 
 #define BIO_INLINE_VECS 4
diff --git a/block/genhd.c b/block/genhd.c
index b3c33495d7208..fe23085ddddd6 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -596,6 +596,7 @@  void del_gendisk(struct gendisk *disk)
 	/*
 	 * Allow using passthrough request again after the queue is torn down.
 	 */
+	blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
 	blk_mq_unfreeze_queue(q);
 
 	if (!(disk->flags & GENHD_FL_HIDDEN)) {