Inside blk_mq_queue_tag_busy_iter() we already grabbed request's refcount before calling ->fn(), so needn't to grab it one more time in blk_mq_check_expired(). Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- block/blk-mq.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index d2725f94491d..4d3457d2957f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -917,6 +917,10 @@ void blk_mq_put_rq_ref(struct request *rq) __blk_mq_free_request(rq); } +/* + * This request won't be re-allocated because its refcount is held when + * calling this callback. + */ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, struct request *rq, void *priv, bool reserved) { @@ -930,27 +934,12 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, return true; /* - * We have reason to believe the request may be expired. Take a - * reference on the request to lock this request lifetime into its - * currently allocated context to prevent it from being reallocated in - * the event the completion by-passes this timeout handler. - * - * If the reference was already released, then the driver beat the - * timeout handler to posting a natural completion. - */ - if (!refcount_inc_not_zero(&rq->ref)) - return true; - - /* - * The request is now locked and cannot be reallocated underneath the - * timeout handler's processing. Re-verify this exact request is truly - * expired; if it is not expired, then the request was completed and - * reallocated as a new request. + * Re-verify this exact request is truly expired; if it is not expired, + * then the request was completed and reallocated as a new request + * after returning from blk_mq_check_expired(). */ if (blk_mq_req_expired(rq, next)) blk_mq_rq_timed_out(rq, reserved); - - blk_mq_put_rq_ref(rq); return true; } -- 2.31.1