mmc: card: fix null pointer deference in cmdq timeout handler
The mmc_queue_req will be present only if the request is issued to the LLD. The request could be fetched from block layer queue but could be waiting to be issued (for e.g. clock scaling is waiting for an empty cmdq queue). Evaluate such cases and reset the timer to give LLD more time. Change-Id: Ic5818f5c2b8356bda9b1612d78b65e07dad011d7 Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
This commit is contained in:
parent
381320b601
commit
d2bfe9d86b
|
@ -3041,18 +3041,38 @@ static enum blk_eh_timer_return mmc_blk_cmdq_req_timed_out(struct request *req)
|
|||
struct mmc_queue *mq = req->q->queuedata;
|
||||
struct mmc_host *host = mq->card->host;
|
||||
struct mmc_queue_req *mq_rq = req->special;
|
||||
struct mmc_request *mrq = &mq_rq->cmdq_req.mrq;
|
||||
struct mmc_cmdq_req *cmdq_req = &mq_rq->cmdq_req;
|
||||
struct mmc_request *mrq;
|
||||
struct mmc_cmdq_req *cmdq_req;
|
||||
|
||||
BUG_ON(!host);
|
||||
|
||||
/*
|
||||
* The mmc_queue_req will be present only if the request
|
||||
* is issued to the LLD. The request could be fetched from
|
||||
* block layer queue but could be waiting to be issued
|
||||
* (for e.g. clock scaling is waiting for an empty cmdq queue)
|
||||
* Reset the timer in such cases to give LLD more time
|
||||
*/
|
||||
if (!mq_rq) {
|
||||
pr_warn("%s: restart timer for tag: %d\n", __func__, req->tag);
|
||||
return BLK_EH_RESET_TIMER;
|
||||
}
|
||||
|
||||
mrq = &mq_rq->cmdq_req.mrq;
|
||||
cmdq_req = &mq_rq->cmdq_req;
|
||||
|
||||
BUG_ON(!mrq || !cmdq_req);
|
||||
|
||||
if (cmdq_req->cmdq_req_flags & DCMD)
|
||||
mrq->cmd->error = -ETIMEDOUT;
|
||||
else
|
||||
mrq->data->error = -ETIMEDOUT;
|
||||
|
||||
BUG_ON(host->err_mrq != NULL);
|
||||
host->err_mrq = mrq;
|
||||
mrq->done(mrq);
|
||||
|
||||
return BLK_EH_NOT_HANDLED;
|
||||
mmc_host_clk_release(mrq->host);
|
||||
return BLK_EH_HANDLED;
|
||||
}
|
||||
|
||||
static void mmc_blk_cmdq_err(struct mmc_queue *mq)
|
||||
|
@ -3131,6 +3151,7 @@ unhalt:
|
|||
mmc_cmdq_halt(host, false);
|
||||
|
||||
out:
|
||||
host->err_mrq = NULL;
|
||||
mmc_rpm_release(host, &card->dev);
|
||||
|
||||
if (test_and_clear_bit(0, &ctx_info->req_starved))
|
||||
|
|
Loading…
Reference in New Issue