From 9bc36b07a2c375ad4fac740f273cf2b83b5cd4e8 Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Thu, 13 Aug 2015 17:58:30 +0300 Subject: [PATCH] mmc: core: kick block queue after unhalting cmdq If request has to be requeued due to cmdq being halted and if we change the task status to interruptible before going to sleep then cmdq thread may not wakeup again. Note that blk_requeue_request() doesn't trigger ->request_fn() again to wakeup the cmdq thread. Fix this issue by kicking the queue once cmdq state machine is unhalted. Change-Id: Icbfb3b6560285fa0a0ce7e83eee66b651d4594a0 Signed-off-by: Gilad Broner Signed-off-by: Subhash Jadavani --- drivers/mmc/card/queue.c | 1 + drivers/mmc/core/core.c | 6 +++++- include/linux/mmc/host.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index ea5d7bf124ac..d226eae5f9f1 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -347,6 +347,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, } else { sema_init(&mq->thread_sem, 1); mq->queue->queuedata = mq; + card->host->cmdq_ctx.q = mq->queue; mq->thread = kthread_run(mmc_cmdq_thread, mq, "mmc-cmdqd/%d%s", host->index, diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index afc7b8c26b22..9f3924db9dc7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -1505,8 +1506,11 @@ int mmc_cmdq_halt(struct mmc_host *host, bool halt) host->ops->notify_halt(host, halt); if (!err && halt) mmc_host_set_halt(host); - else if (!err && !halt) + else if (!err && !halt) { mmc_host_clr_halt(host); + if (host->cmdq_ctx.q) + blk_run_queue(host->cmdq_ctx.q); + } } else { err = -ENOSYS; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c6d0ff9f1cbe..aa9df4ce96e5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -257,6 +257,7 @@ struct mmc_cmdq_context_info { /* no free tag available */ unsigned long req_starved; wait_queue_head_t queue_empty_wq; + struct request_queue *q; }; /**