Skip to content

Commit

Permalink
mmc: block: Fix unsupported parallel dispatch of requests
Browse files Browse the repository at this point in the history
The mmc block driver does not support parallel dispatch of requests. In
normal circumstances, all requests are anyway funneled through a single
work item, so parallel dispatch never happens. However it can happen if
there is no elevator.

Fix that by detecting if a dispatch is in progress and returning busy
(BLK_STS_RESOURCE) in that case

Fixes: 8119697 ("mmc: block: Add blk-mq support")
Cc: stable@vger.kernel.org # v4.16+
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Adrian Hunter authored and Ulf Hansson committed Aug 21, 2018
1 parent 17e96d8 commit 26caddf
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
12 changes: 7 additions & 5 deletions drivers/mmc/core/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,6 @@ static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req,
mmc_exit_request(mq->queue, req);
}

/*
* We use BLK_MQ_F_BLOCKING and have only 1 hardware queue, which means requests
* will not be dispatched in parallel.
*/
static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{
Expand All @@ -264,7 +260,7 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,

spin_lock_irq(q->queue_lock);

if (mq->recovery_needed) {
if (mq->recovery_needed || mq->busy) {
spin_unlock_irq(q->queue_lock);
return BLK_STS_RESOURCE;
}
Expand All @@ -291,6 +287,9 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
break;
}

/* Parallel dispatch of requests is not supported at the moment */
mq->busy = true;

mq->in_flight[issue_type] += 1;
get_card = (mmc_tot_in_flight(mq) == 1);
cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
Expand Down Expand Up @@ -333,9 +332,12 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
mq->in_flight[issue_type] -= 1;
if (mmc_tot_in_flight(mq) == 0)
put_card = true;
mq->busy = false;
spin_unlock_irq(q->queue_lock);
if (put_card)
mmc_put_card(card, &mq->ctx);
} else {
WRITE_ONCE(mq->busy, false);
}

return ret;
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/core/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct mmc_queue {
unsigned int cqe_busy;
#define MMC_CQE_DCMD_BUSY BIT(0)
#define MMC_CQE_QUEUE_FULL BIT(1)
bool busy;
bool use_cqe;
bool recovery_needed;
bool in_recovery;
Expand Down

0 comments on commit 26caddf

Please sign in to comment.