From 4aed61f8c208f22e83f1c8c31b7bd2995374f0a7 Mon Sep 17 00:00:00 2001 From: Jonathan Bell Date: Tue, 15 Oct 2024 11:22:53 +0100 Subject: [PATCH] mmc: don't reference requests after finishing them Posted write tracking introduced in the commit below raced with re-use of the requests between completion and submission, potentially causing underflow of the pending write count. Fixes: e6c1e862b2b8 ("mmc: restrict posted write counts for SD cards in CQ mode") Signed-off-by: Jonathan Bell --- drivers/mmc/core/block.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 04c45326e060..dbba6a636aed 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1550,6 +1550,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) struct request_queue *q = req->q; struct mmc_host *host = mq->card->host; enum mmc_issue_type issue_type = mmc_issue_type(mq, req); + bool write = req_op(req) == REQ_OP_WRITE; unsigned long flags; bool put_card; int err; @@ -1581,7 +1582,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) spin_lock_irqsave(&mq->lock, flags); - if (req_op(req) == REQ_OP_WRITE) + if (write) mq->pending_writes--; mq->in_flight[issue_type] -= 1; @@ -2200,15 +2201,16 @@ static void mmc_blk_mq_poll_completion(struct mmc_queue *mq, } static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type, - struct request *req) + bool write) { unsigned long flags; bool put_card; spin_lock_irqsave(&mq->lock, flags); - if (req_op(req) == REQ_OP_WRITE) + if (write) mq->pending_writes--; + mq->in_flight[issue_type] -= 1; put_card = (mmc_tot_in_flight(mq) == 0); @@ -2223,6 +2225,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req, bool can_sleep) { enum mmc_issue_type issue_type = mmc_issue_type(mq, req); + bool write = req_op(req) == REQ_OP_WRITE; struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); struct mmc_request *mrq = &mqrq->brq.mrq; struct mmc_host *host = mq->card->host; @@ -2242,7 +2245,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req, blk_mq_complete_request(req); } - mmc_blk_mq_dec_in_flight(mq, issue_type, req); + mmc_blk_mq_dec_in_flight(mq, issue_type, write); } void mmc_blk_mq_recovery(struct mmc_queue *mq)