Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e73adf4e authored by Veerabhadrarao Badiganti's avatar Veerabhadrarao Badiganti
Browse files

mmc: card: Requeue the request if it fails during issuing



In the cmdq request issuing path, cq driver invokes ICE driver calls
to get the configuration for encrypting/decrypting the data requests.
The ice driver in-turn makes calls to secure world (TZ) which can
process only single task at a time. If TZ is busy in servicing
something else when ICE driver invokes it, ICE driver would return
-EBUSY to cmdq driver.

The requests which failed due to ice error are neither issued to h/w
nor errored out, so resulting in filesystem corruptions.

We must re-queue the requests which failed with -EBUSY error, so that
it will be re-issued again as very next request.

Change-Id: I4557a5c3aca8dd53740e48e516e6011787df50d8
Signed-off-by: default avatarVeerabhadrarao Badiganti <vbadigan@codeaurora.org>
parent 4efc0a60
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -3184,6 +3184,16 @@ static struct mmc_cmdq_req *mmc_blk_cmdq_rw_prep(
	return &mqrq->cmdq_req;
}

static void mmc_blk_cmdq_requeue_rw_rq(struct mmc_queue *mq,
				struct request *req)
{
	struct mmc_card *card = mq->card;
	struct mmc_host *host = card->host;

	blk_requeue_request(req->q, req);
	mmc_put_card(host->card);
}

static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
{
	struct mmc_queue_req *active_mqrq;
@@ -3231,6 +3241,15 @@ static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
		wait_event_interruptible(ctx->queue_empty_wq,
					(!ctx->active_reqs));

	if (ret) {
		/* clear pending request */
		WARN_ON(!test_and_clear_bit(req->tag,
				&host->cmdq_ctx.data_active_reqs));
		WARN_ON(!test_and_clear_bit(req->tag,
				&host->cmdq_ctx.active_reqs));
		mmc_cmdq_clk_scaling_stop_busy(host, true, false);
	}

	return ret;
}

@@ -4058,6 +4077,13 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
			ret = mmc_blk_cmdq_issue_flush_rq(mq, req);
		} else {
			ret = mmc_blk_cmdq_issue_rw_rq(mq, req);
			/*
			 * If issuing of the request fails with eitehr EBUSY or
			 * EAGAIN error, re-queue the request.
			 * This case would occur with ICE calls.
			 */
			if (ret == -EBUSY || ret == -EAGAIN)
				mmc_blk_cmdq_requeue_rw_rq(mq, req);
		}
	}