diff mbox series

block: fix missing queue put in error path

Message ID f39193ff-bc6b-53fa-dc05-3127012d70c5@kernel.dk (mailing list archive)
State New, archived
Headers show
Series block: fix missing queue put in error path | expand

Commit Message

Jens Axboe Nov. 15, 2021, 9:35 p.m. UTC
If we fail the submission queue checks, we don't put the queue afterwards.
This can cause various issues like stalls on scheduler switch or failure
to remove the device, or like in the original bug report, timeout waiting
for the device on reboot/restart.

While in there, fix a few whitespace discrepancies in the surrounding
code.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=215039
Fixes: b637108a4022 ("blk-mq: fix filesystem I/O request allocation")
Reported-and-tested-by: Stephen Smith <stephenmsmith@blueyonder.co.uk>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

---

Comments

Ming Lei Nov. 15, 2021, 11:57 p.m. UTC | #1
On Mon, Nov 15, 2021 at 02:35:09PM -0700, Jens Axboe wrote:
> If we fail the submission queue checks, we don't put the queue afterwards.
> This can cause various issues like stalls on scheduler switch or failure
> to remove the device, or like in the original bug report, timeout waiting
> for the device on reboot/restart.
> 
> While in there, fix a few whitespace discrepancies in the surrounding
> code.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=215039
> Fixes: b637108a4022 ("blk-mq: fix filesystem I/O request allocation")
> Reported-and-tested-by: Stephen Smith <stephenmsmith@blueyonder.co.uk>
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> 
> ---
> 
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 3ab34c4f20da..5e1c9fd99353 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -2543,8 +2543,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
>  	return NULL;
>  }
>  
> -static inline bool blk_mq_can_use_cached_rq(struct request *rq,
> -		struct bio *bio)
> +static inline bool blk_mq_can_use_cached_rq(struct request *rq, struct bio *bio)
>  {
>  	if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
>  		return false;
> @@ -2565,7 +2564,6 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
>  	bool checked = false;
>  
>  	if (plug) {
> -
>  		rq = rq_list_peek(&plug->cached_rq);
>  		if (rq && rq->q == q) {
>  			if (unlikely(!submit_bio_checks(bio)))
> @@ -2587,12 +2585,14 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
>  fallback:
>  	if (unlikely(bio_queue_enter(bio)))
>  		return NULL;
> -	if (!checked && !submit_bio_checks(bio))
> -		return NULL;
> +	if (unlikely(!checked && !submit_bio_checks(bio)))
> +		goto out_put;
>  	rq = blk_mq_get_new_requests(q, plug, bio, nsegs, same_queue_rq);
> -	if (!rq)
> -		blk_queue_exit(q);
> -	return rq;
> +	if (rq)
> +		return rq;
> +out_put:
> +	blk_queue_exit(q);
> +	return NULL;

Reviewed-by: Ming Lei <ming.lei@redhat.com>
diff mbox series

Patch

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 3ab34c4f20da..5e1c9fd99353 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2543,8 +2543,7 @@  static struct request *blk_mq_get_new_requests(struct request_queue *q,
 	return NULL;
 }
 
-static inline bool blk_mq_can_use_cached_rq(struct request *rq,
-		struct bio *bio)
+static inline bool blk_mq_can_use_cached_rq(struct request *rq, struct bio *bio)
 {
 	if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
 		return false;
@@ -2565,7 +2564,6 @@  static inline struct request *blk_mq_get_request(struct request_queue *q,
 	bool checked = false;
 
 	if (plug) {
-
 		rq = rq_list_peek(&plug->cached_rq);
 		if (rq && rq->q == q) {
 			if (unlikely(!submit_bio_checks(bio)))
@@ -2587,12 +2585,14 @@  static inline struct request *blk_mq_get_request(struct request_queue *q,
 fallback:
 	if (unlikely(bio_queue_enter(bio)))
 		return NULL;
-	if (!checked && !submit_bio_checks(bio))
-		return NULL;
+	if (unlikely(!checked && !submit_bio_checks(bio)))
+		goto out_put;
 	rq = blk_mq_get_new_requests(q, plug, bio, nsegs, same_queue_rq);
-	if (!rq)
-		blk_queue_exit(q);
-	return rq;
+	if (rq)
+		return rq;
+out_put:
+	blk_queue_exit(q);
+	return NULL;
 }
 
 /**