From: Adrian Hunter <adrian.hunter@intel.com>
To: Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-mmc <linux-mmc@vger.kernel.org>,
Alex Lemberg <alex.lemberg@sandisk.com>,
Mateusz Nowak <mateusz.nowak@intel.com>,
Yuliy Izrailov <Yuliy.Izrailov@sandisk.com>,
Jaehoon Chung <jh80.chung@samsung.com>,
Dong Aisheng <dongas86@gmail.com>,
Das Asutosh <asutoshd@codeaurora.org>,
Zhangfei Gao <zhangfei.gao@gmail.com>,
Sujit Reddy Thumma <sthumma@codeaurora.org>,
Dorfman Konstantin <kdorfman@codeaurora.org>,
David Griego <david.griego@linaro.org>,
Sahitya Tummala <stummala@codeaurora.org>,
Harjani Ritesh <riteshh@codeaurora.org>
Subject: [PATCH RFC 23/46] mmc: queue: Fix queue thread wake-up
Date: Thu, 9 Jun 2016 14:52:23 +0300 [thread overview]
Message-ID: <1465473166-22532-24-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1465473166-22532-1-git-send-email-adrian.hunter@intel.com>
The only time the driver sleeps expecting to be woken upon the arrival of
a new request, is when the dispatch queue is empty. The only time that it
is known whether the dispatch queue is empty is after NULL is returned
from blk_fetch_request() while under the queue lock.
Recognizing those facts, simplify the synchronization between the queue
thread and the request function. A couple of flags tell the request
function what to do, and the queue lock and barriers associated with
wake-ups ensure synchronization.
The result is simpler and allows the removal of the context_info lock.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/card/block.c | 7 -------
drivers/mmc/card/queue.c | 35 +++++++++++++++++++++--------------
drivers/mmc/card/queue.h | 1 +
drivers/mmc/core/core.c | 6 ------
include/linux/mmc/host.h | 2 --
5 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5345730c6eeb..7e69dceaf645 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2146,8 +2146,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
int ret;
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
- struct mmc_host *host = card->host;
- unsigned long flags;
unsigned int cmd_flags = req ? req->cmd_flags : 0;
if (req && !mq->mqrq_prev->req)
@@ -2178,11 +2176,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
mmc_blk_issue_rw_rq(mq, NULL);
ret = mmc_blk_issue_flush(mq, req);
} else {
- if (!req && host->areq) {
- spin_lock_irqsave(&host->context_info.lock, flags);
- host->context_info.is_waiting_last_req = true;
- spin_unlock_irqrestore(&host->context_info.lock, flags);
- }
ret = mmc_blk_issue_rw_rq(mq, req);
}
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 6f4323c6d653..7469d0d99027 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -50,6 +50,7 @@ static int mmc_queue_thread(void *d)
{
struct mmc_queue *mq = d;
struct request_queue *q = mq->queue;
+ struct mmc_context_info *cntx = &mq->card->host->context_info;
current->flags |= PF_MEMALLOC;
@@ -61,6 +62,19 @@ static int mmc_queue_thread(void *d)
spin_lock_irq(q->queue_lock);
set_current_state(TASK_INTERRUPTIBLE);
req = blk_fetch_request(q);
+ mq->asleep = false;
+ cntx->is_waiting_last_req = false;
+ cntx->is_new_req = false;
+ if (!req) {
+ /*
+ * Dispatch queue is empty so set flags for
+ * mmc_request_fn() to wake us up.
+ */
+ if (mq->mqrq_prev->req)
+ cntx->is_waiting_last_req = true;
+ else
+ mq->asleep = true;
+ }
mq->mqrq_cur->req = req;
spin_unlock_irq(q->queue_lock);
@@ -112,7 +126,6 @@ static void mmc_request_fn(struct request_queue *q)
{
struct mmc_queue *mq = q->queuedata;
struct request *req;
- unsigned long flags;
struct mmc_context_info *cntx;
if (!mq) {
@@ -124,19 +137,13 @@ static void mmc_request_fn(struct request_queue *q)
}
cntx = &mq->card->host->context_info;
- if (!mq->mqrq_cur->req && mq->mqrq_prev->req) {
- /*
- * New MMC request arrived when MMC thread may be
- * blocked on the previous request to be complete
- * with no current request fetched
- */
- spin_lock_irqsave(&cntx->lock, flags);
- if (cntx->is_waiting_last_req) {
- cntx->is_new_req = true;
- wake_up_interruptible(&cntx->wait);
- }
- spin_unlock_irqrestore(&cntx->lock, flags);
- } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
+
+ if (cntx->is_waiting_last_req) {
+ cntx->is_new_req = true;
+ wake_up_interruptible(&cntx->wait);
+ }
+
+ if (mq->asleep)
wake_up_process(mq->thread);
}
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 36cddab57d77..872c82a83729 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -51,6 +51,7 @@ struct mmc_queue {
unsigned int flags;
#define MMC_QUEUE_SUSPENDED (1 << 0)
#define MMC_QUEUE_NEW_REQUEST (1 << 1)
+ bool asleep;
int (*issue_fn)(struct mmc_queue *, struct request *);
void *data;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8563dc9e1519..2c50883f3845 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -501,18 +501,14 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
struct mmc_command *cmd;
struct mmc_context_info *context_info = &host->context_info;
int err;
- unsigned long flags;
while (1) {
wait_event_interruptible(context_info->wait,
(context_info->is_done_rcv ||
context_info->is_new_req));
- spin_lock_irqsave(&context_info->lock, flags);
context_info->is_waiting_last_req = false;
- spin_unlock_irqrestore(&context_info->lock, flags);
if (context_info->is_done_rcv) {
context_info->is_done_rcv = false;
- context_info->is_new_req = false;
cmd = mrq->cmd;
if (!cmd->error || !cmd->retries ||
@@ -531,7 +527,6 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
continue; /* wait for done/new event again */
}
} else if (context_info->is_new_req) {
- context_info->is_new_req = false;
if (!next_req)
return MMC_BLK_NEW_REQUEST;
}
@@ -2939,7 +2934,6 @@ void mmc_unregister_pm_notifier(struct mmc_host *host)
*/
void mmc_init_context_info(struct mmc_host *host)
{
- spin_lock_init(&host->context_info.lock);
host->context_info.is_new_req = false;
host->context_info.is_done_rcv = false;
host->context_info.is_waiting_last_req = false;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index af247e4c75d5..567c6c14c9f3 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -198,14 +198,12 @@ struct mmc_slot {
* @is_new_req wake up reason was new request
* @is_waiting_last_req mmc context waiting for single running request
* @wait wait queue
- * @lock lock to protect data fields
*/
struct mmc_context_info {
bool is_done_rcv;
bool is_new_req;
bool is_waiting_last_req;
wait_queue_head_t wait;
- spinlock_t lock;
};
struct regulator;
--
1.9.1
next prev parent reply other threads:[~2016-06-09 11:58 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-09 11:52 [PATCH RFC 00/46] mmc: mmc: Add Software Command Queuing Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 01/46] mmc: core: Add support for sending commands during data transfer Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 02/46] mmc: mmc_test: Add tests for sending commands during transfer Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 03/46] mmc: sdhci: Move busy signal handling into sdhci_finish_cmd() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 04/46] mmc: sdhci: Get rid of redundant BUG_ONs Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 05/46] mmc: sdhci: Simplify sdhci_finish_command() by clearing host->cmd at the start Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 06/46] mmc: sdhci: Record what command is using the data lines Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 07/46] mmc: sdhci: Get rid of host->busy_handle Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 08/46] mmc: sdhci: Reduce the use of host->mrq Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 09/46] mmc: sdhci: Move host->data warning Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 10/46] mmc: sdhci: Factor out sdhci_finish_mrq() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 11/46] mmc: sdhci: Factor out sdhci_needs_reset() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 12/46] mmc: sdhci: Track whether a reset is pending Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 13/46] mmc: sdhci: Clear pointers when a request finishes Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 14/46] mmc: sdhci: Ensure all requests get errored out Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 15/46] mmc: sdhci: Factor out sdhci_data_line_cmd() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 16/46] mmc: sdhci: Separate timer timeout for command and data requests Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 17/46] mmc: sdhci: Allow for finishing multiple requests Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 18/46] mmc: sdhci: Factor out sdhci_auto_cmd12() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 19/46] mmc: sdhci: Do not reset cmd or data circuits that are in use Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 20/46] mmc: sdhci: Support cap_cmd_during_tfr requests Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 21/46] mmc: sdhci-pci: Set MMC_CAP_CMD_DURING_TFR for Intel eMMC controllers Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 22/46] mmc: sdhci-acpi: " Adrian Hunter
2016-06-09 11:52 ` Adrian Hunter [this message]
2016-06-09 11:52 ` [PATCH RFC 24/46] mmc: queue: Factor out mmc_queue_alloc_bounce_bufs() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 25/46] mmc: queue: Factor out mmc_queue_alloc_bounce_sgs() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 26/46] mmc: queue: Factor out mmc_queue_alloc_sgs() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 27/46] mmc: queue: Factor out mmc_queue_reqs_free_bufs() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 28/46] mmc: queue: Introduce queue depth Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 29/46] mmc: queue: Use queue depth to allocate and free Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 30/46] mmc: queue: Allocate queue of size qdepth Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 31/46] mmc: mmc: Add Command Queue definitions Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 32/46] mmc: mmc: Add functions to enable / disable the Command Queue Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 33/46] mmc: mmc_test: Disable Command Queue while mmc_test is used Adrian Hunter
2016-06-10 10:44 ` [PATCH RFC V2 " Adrian Hunter
2016-06-10 10:59 ` Venu Byravarasu
2016-06-10 11:36 ` Adrian Hunter
2016-06-10 12:03 ` Venu Byravarasu
2016-06-09 11:52 ` [PATCH RFC 34/46] mmc: block: Disable Command Queue while RPMB " Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 35/46] mmc: core: Do not prepare a new request twice Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 36/46] mmc: core: Export mmc_retune_hold() and mmc_retune_release() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 37/46] mmc: block: Factor out mmc_blk_requeue() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 38/46] mmc: block: Fix 4K native sector check Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 39/46] mmc: block: Use local var for mqrq_cur Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 40/46] mmc: block: Pass mqrq to mmc_blk_prep_packed_list() Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 41/46] mmc: block: Introduce queue semantics Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 42/46] mmc: queue: Add a function to control wake-up on new requests Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 43/46] mmc: block: Add Software Command Queuing Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 44/46] mmc: mmc: Enable " Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 45/46] mmc: sdhci-pci: Enable Software Command Queuing for some Intel controllers Adrian Hunter
2016-06-09 11:52 ` [PATCH RFC 46/46] mmc: sdhci-acpi: " Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1465473166-22532-24-git-send-email-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=Yuliy.Izrailov@sandisk.com \
--cc=alex.lemberg@sandisk.com \
--cc=asutoshd@codeaurora.org \
--cc=david.griego@linaro.org \
--cc=dongas86@gmail.com \
--cc=jh80.chung@samsung.com \
--cc=kdorfman@codeaurora.org \
--cc=linux-mmc@vger.kernel.org \
--cc=mateusz.nowak@intel.com \
--cc=riteshh@codeaurora.org \
--cc=sthumma@codeaurora.org \
--cc=stummala@codeaurora.org \
--cc=ulf.hansson@linaro.org \
--cc=zhangfei.gao@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).