Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1488901 > unrolled thread
| Started by | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| First post | 2016-09-22 16:00 +0200 |
| Last post | 2016-09-22 16:10 +0200 |
| Articles | 6 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH PoC 0/7] mmc: switch to blk-mq Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:00 +0200
[PATCH PoC 1/7] mmc-mq: add debug printks Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:00 +0200
[PATCH PoC 2/7] mmc-mq: remove async requests support Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:00 +0200
[PATCH PoC 6/7] mmc-mq: initial blk-mq support Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:00 +0200
[PATCH PoC 5/7] mmc-mq: remove some debug printks Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:00 +0200
[PATCH PoC 4/7] mmc-mq: implement checking for queue busy condition Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> - 2016-09-22 16:10 +0200
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:00 +0200 |
| Subject | [PATCH PoC 0/7] mmc: switch to blk-mq |
| Message-ID | <skcHE-74T-7@gated-at.bofh.it> |
Hi, Since Linus Walleij is also working on that and I won't probably have time to touch this code till the end of upcoming month, here it is (basically a code dump of my proof-of-concept work). I hope that it would be useful to somebody. It is extremely ugly & full of bogus debug code but boots fine on my Odroid-XU3 and benchmarks can be run. The patchset is based on top of patches up to "[PATCH v3 24/30] mmc: block: Introduce queue semantics" patch from "[PATCH V3 00/30] mmc: mmc: dd Software Command Queuing" series by Adrian Hunter: http://www.spinics.net/lists/linux-mmc/msg38013.html [ It was commmit f3ba397441825f99edb4833a5f52dd2355d253c7 in swcmdq branch from: http://git.infradead.org/users/ahunter/linux-sdhci.git Unfortunalty it got rebased later to V4 -- my patchset probably still applies and works fine but I have not tested this yet. ] PS Linus, I got async requests support working, see patch #7. You may be able to use this method depending on the hackiness level of your patches. ;) Initial benchmark results: root@target:~# time dd if=/dev/mmcblk0 of=/dev/null bs=4k vanilla - performance governor - 1300MHz/1800MHz 15758000128 bytes (16 GB) copied, 69.8334 s, 226 MB/s blk-mq - performance governor - 1300MHz/1800MHz 15758000128 bytes (16 GB) copied, 79.0868 s, 199 MB/s vanilla - performance governor - 200MHz/200MHz 15758000128 bytes (16 GB) copied, 228.014 s, 69.1 MB/s blk-mq - performance governor - 200MHz/200MHz 15758000128 bytes (16 GB) copied, 208.536 s, 75.6 MB/s vanilla - on-demand governor - 1300MHz/1800MHz 15758000128 bytes (16 GB) copied, 77.0968 s, 204 MB/s blk-mq - on-demand governor - 1300/1800MHz 15758000128 bytes (16 GB) copied, 96.351 s, 164 MB/s root@target:~# time dd if=/dev/mmcblk0 of=/dev/null vanilla - on-demand governor - 1300MHz/1800MHz 15758000128 bytes (16 GB) copied, 155.149 s, 102 MB/s blk-mq - on-demand governor - 1300MHz/1800MHz 15758000128 bytes (16 GB) copied, 106.122 s, 148 MB/s Bartlomiej Zolnierkiewicz (7): mmc-mq: add debug printks mmc-mq: remove async requests support mmc-mq: request completion fixes mmc-mq: implement checking for queue busy condition mmc-mq: remove some debug printks mmc-mq: initial blk-mq support mmc-mq: async request support for blk-mq mode drivers/mmc/card/block.c | 174 +++++++++++++------------- drivers/mmc/card/mmc_test.c | 8 +- drivers/mmc/card/queue.c | 262 ++++++++++++++++++++++++++------------ drivers/mmc/card/queue.h | 50 +++++++- drivers/mmc/core/bus.c | 2 - drivers/mmc/core/core.c | 299 +++++++++++++++++++++++++++++--------------- drivers/mmc/core/core.h | 2 - drivers/mmc/core/mmc_ops.c | 9 ++ drivers/mmc/host/dw_mmc.c | 3 +- include/linux/mmc/card.h | 1 - include/linux/mmc/core.h | 6 +- include/linux/mmc/host.h | 15 --- 12 files changed, 529 insertions(+), 302 deletions(-) -- 1.9.1
[toc] | [next] | [standalone]
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:00 +0200 |
| Subject | [PATCH PoC 1/7] mmc-mq: add debug printks |
| Message-ID | <skcHF-74T-41@gated-at.bofh.it> |
| In reply to | #1488901 |
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
drivers/mmc/card/block.c | 18 ++++++++++++++++--
drivers/mmc/core/core.c | 32 ++++++++++++++++++++++++++++++--
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 7d733d0..ce56930 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1995,6 +1995,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
const u8 packed_nr = 2;
u8 reqs = 0;
+ pr_info("%s: enter\n", __func__);
if (rqc) {
mqrq_cur = mmc_queue_req_find(mq, rqc);
if (!mqrq_cur) {
@@ -2004,8 +2005,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
}
}
- if (!mq->qcnt)
+ if (!mq->qcnt) {
+ pr_info("%s: exit (0) (!mq->qcnt)\n", __func__);
return 0;
+ }
if (mqrq_cur)
reqs = mmc_blk_prep_packed_list(mq, mqrq_cur);
@@ -2035,8 +2038,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
} else
areq = NULL;
areq = mmc_start_req(card->host, areq, (int *) &status);
- if (!areq)
+ if (!areq) {
+ pr_info("%s: exit (0) (!areq)\n", __func__);
return 0;
+ }
mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
brq = &mq_rq->brq;
@@ -2150,6 +2155,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
mmc_queue_req_free(mq, mq_rq);
+ pr_info("%s: exit (1)\n", __func__);
return 1;
cmd_abort:
@@ -2184,6 +2190,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
mmc_queue_req_free(mq, mq_rq);
+ pr_info("%s: exit (0)\n", __func__);
return 0;
}
@@ -2194,10 +2201,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
struct mmc_card *card = md->queue.card;
unsigned int cmd_flags = req ? req->cmd_flags : 0;
+ pr_info("%s: enter\n", __func__);
+
if (req && !mq->qcnt)
/* claim host only for the first request */
mmc_get_card(card);
+ pr_info("%s: mmc_blk_part_switch\n", __func__);
ret = mmc_blk_part_switch(card, md);
if (ret) {
if (req) {
@@ -2208,6 +2218,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
}
if (cmd_flags & REQ_DISCARD) {
+ pr_info("%s: DISCARD rq\n", __func__);
/* complete ongoing async transfer before issuing discard */
if (mq->qcnt)
mmc_blk_issue_rw_rq(mq, NULL);
@@ -2216,11 +2227,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
else
ret = mmc_blk_issue_discard_rq(mq, req);
} else if (cmd_flags & REQ_FLUSH) {
+ pr_info("%s: FLUSH rq\n", __func__);
/* complete ongoing async transfer before issuing flush */
if (mq->qcnt)
mmc_blk_issue_rw_rq(mq, NULL);
ret = mmc_blk_issue_flush(mq, req);
} else {
+ pr_info("%s: RW rq\n", __func__);
ret = mmc_blk_issue_rw_rq(mq, req);
}
@@ -2228,6 +2241,7 @@ out:
/* Release host when there are no more requests */
if (!mq->qcnt)
mmc_put_card(card);
+ pr_info("%s: exit\n", __func__);
return ret;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 9be42691..d2d8d9b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -219,6 +219,8 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{
int err;
+ pr_info("%s: enter\n", __func__);
+
/* Assumes host controller has been runtime resumed by mmc_claim_host */
err = mmc_retune(host);
if (err) {
@@ -256,6 +258,8 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
trace_mmc_request_start(host, mrq);
host->ops->request(host, mrq);
+
+ pr_info("%s: exit\n", __func__);
}
static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
@@ -264,6 +268,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
unsigned int i, sz;
struct scatterlist *sg;
#endif
+ pr_info("%s: enter\n", __func__);
mmc_retune_hold(host);
if (mmc_card_removed(host->card))
@@ -327,6 +332,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
led_trigger_event(host->led, LED_FULL);
__mmc_start_request(host, mrq);
+ pr_info("%s: exit\n", __func__);
return 0;
}
@@ -466,6 +472,8 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
{
int err;
+ pr_info("%s: enter\n", __func__);
+
mmc_wait_ongoing_tfr_cmd(host);
init_completion(&mrq->completion);
@@ -480,6 +488,8 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
complete(&mrq->completion);
}
+ pr_info("%s: exit\n", __func__);
+
return err;
}
@@ -502,10 +512,14 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
struct mmc_context_info *context_info = &host->context_info;
int err;
+ pr_info("%s: enter\n", __func__);
+
while (1) {
wait_event_interruptible(context_info->wait,
+// context_info->is_done_rcv);
(context_info->is_done_rcv ||
context_info->is_new_req));
+ pr_info("%s: waiting done\n", __func__);
context_info->is_waiting_last_req = false;
if (context_info->is_done_rcv) {
context_info->is_done_rcv = false;
@@ -527,11 +541,14 @@ 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) {
- if (!next_req)
+ if (!next_req) {
+ pr_info("%s: exit (!next_req)\n", __func__);
return MMC_BLK_NEW_REQUEST;
+ }
}
}
mmc_retune_release(host);
+ pr_info("%s: exit (err=%d)\n", __func__, err);
return err;
}
@@ -539,8 +556,11 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
{
struct mmc_command *cmd;
+ pr_info("%s: enter\n", __func__);
+
while (1) {
wait_for_completion(&mrq->completion);
+ pr_info("%s: waiting done\n", __func__);
cmd = mrq->cmd;
@@ -567,7 +587,7 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
mmc_retune_recheck(host);
- pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
+ pr_info("%s: req failed (CMD%u): %d, retrying...\n",
mmc_hostname(host), cmd->opcode, cmd->error);
cmd->retries--;
cmd->error = 0;
@@ -575,6 +595,8 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
}
mmc_retune_release(host);
+
+ pr_info("%s: exit\n", __func__);
}
EXPORT_SYMBOL(mmc_wait_for_req_done);
@@ -656,6 +678,10 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
int start_err = 0;
struct mmc_async_req *data = host->areq;
+ pr_info("%s: enter\n", __func__);
+
+ pr_info("%s: areq=%p host->areq=%p\n", __func__, areq, host->areq);
+
/* Prepare a new request */
if (areq && !areq->pre_req_done) {
areq->pre_req_done = true;
@@ -671,6 +697,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
* The previous request was not completed,
* nothing to return
*/
+ pr_info("%s: exit (NULL)\n", __func__);
return NULL;
}
/*
@@ -714,6 +741,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
if (error)
*error = err;
+ pr_info("%s: exit (data=%p)\n", __func__, data);
return data;
}
EXPORT_SYMBOL(mmc_start_req);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:00 +0200 |
| Subject | [PATCH PoC 2/7] mmc-mq: remove async requests support |
| Message-ID | <skcHF-74T-43@gated-at.bofh.it> |
| In reply to | #1488901 |
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
drivers/mmc/card/block.c | 62 ++++++++++++--------------
drivers/mmc/card/queue.c | 113 +++++++++++++++--------------------------------
drivers/mmc/card/queue.h | 5 +--
drivers/mmc/core/bus.c | 2 -
drivers/mmc/core/core.c | 110 +++++++++------------------------------------
drivers/mmc/core/core.h | 2 -
include/linux/mmc/card.h | 1 -
include/linux/mmc/host.h | 15 -------
8 files changed, 85 insertions(+), 225 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index ce56930..1d4a09f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1192,7 +1192,7 @@ int mmc_access_rpmb(struct mmc_queue *mq)
return false;
}
-static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
+static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req, struct mmc_queue_req *mqrq)
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
@@ -1230,13 +1230,14 @@ out:
goto retry;
if (!err)
mmc_blk_reset_success(md, type);
+ mmc_queue_req_free(mq, mqrq);
blk_end_request(req, err, blk_rq_bytes(req));
return err ? 0 : 1;
}
static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
- struct request *req)
+ struct request *req, struct mmc_queue_req *mqrq)
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
@@ -1297,12 +1298,13 @@ out_retry:
if (!err)
mmc_blk_reset_success(md, type);
out:
+ mmc_queue_req_free(mq, mqrq);
blk_end_request(req, err, blk_rq_bytes(req));
return err ? 0 : 1;
}
-static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
+static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req, struct mmc_queue_req *mqrq)
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
@@ -1312,6 +1314,7 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
if (ret)
ret = -EIO;
+ mmc_queue_req_free(mq, mqrq);
blk_end_request_all(req, ret);
return ret ? 0 : 1;
@@ -1918,6 +1921,7 @@ static int mmc_blk_end_packed_req(struct mmc_queue_req *mq_rq)
int idx = packed->idx_failure, i = 0;
int ret = 0;
+ BUG();
BUG_ON(!packed);
while (!list_empty(&packed->list)) {
@@ -1981,7 +1985,7 @@ static void mmc_blk_revert_packed_req(struct mmc_queue *mq,
mmc_blk_clear_packed(mq_rq);
}
-static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
+static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct mmc_queue_req *mqrq)
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
@@ -1990,20 +1994,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
enum mmc_blk_status status;
struct mmc_queue_req *mqrq_cur = NULL;
struct mmc_queue_req *mq_rq;
- struct request *req;
+ struct request *rqc = NULL, *req;
struct mmc_async_req *areq;
const u8 packed_nr = 2;
u8 reqs = 0;
pr_info("%s: enter\n", __func__);
- if (rqc) {
- mqrq_cur = mmc_queue_req_find(mq, rqc);
- if (!mqrq_cur) {
- WARN_ON(1);
- mmc_blk_requeue(mq->queue, rqc);
- rqc = NULL;
- }
- }
+ mqrq_cur = mqrq;
+ rqc = mqrq_cur->req;
if (!mq->qcnt) {
pr_info("%s: exit (0) (!mq->qcnt)\n", __func__);
@@ -2059,10 +2057,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
if (mmc_packed_cmd(mq_rq->cmd_type)) {
ret = mmc_blk_end_packed_req(mq_rq);
+ mmc_queue_req_free(mq, mq_rq); //
+ pr_info("%s: freeing mqrq (packed)\n", __func__); //
break;
} else {
- ret = blk_end_request(req, 0,
- brq->data.bytes_xfered);
+ int bytes = brq->data.bytes_xfered;
+ mmc_queue_req_free(mq, mq_rq); //
+ pr_info("%s: freeing mqrq\n", __func__); //
+ ret = blk_end_request(req, 0, bytes);
}
/*
@@ -2153,9 +2155,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
}
} while (ret);
- mmc_queue_req_free(mq, mq_rq);
-
- pr_info("%s: exit (1)\n", __func__);
+ pr_info("%s: exit (1==ok)\n", __func__);
return 1;
cmd_abort:
@@ -2194,7 +2194,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
return 0;
}
-static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
+static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req, struct mmc_queue_req *mqrq)
{
int ret;
struct mmc_blk_data *md = mq->data;
@@ -2203,9 +2203,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
pr_info("%s: enter\n", __func__);
- if (req && !mq->qcnt)
- /* claim host only for the first request */
- mmc_get_card(card);
+ BUG_ON(!req);
+
+ /* claim host only for the first request */
+ mmc_get_card(card);
pr_info("%s: mmc_blk_part_switch\n", __func__);
ret = mmc_blk_part_switch(card, md);
@@ -2219,28 +2220,21 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
if (cmd_flags & REQ_DISCARD) {
pr_info("%s: DISCARD rq\n", __func__);
- /* complete ongoing async transfer before issuing discard */
- if (mq->qcnt)
- mmc_blk_issue_rw_rq(mq, NULL);
if (req->cmd_flags & REQ_SECURE)
- ret = mmc_blk_issue_secdiscard_rq(mq, req);
+ ret = mmc_blk_issue_secdiscard_rq(mq, req, mqrq);
else
- ret = mmc_blk_issue_discard_rq(mq, req);
+ ret = mmc_blk_issue_discard_rq(mq, req, mqrq);
} else if (cmd_flags & REQ_FLUSH) {
pr_info("%s: FLUSH rq\n", __func__);
- /* complete ongoing async transfer before issuing flush */
- if (mq->qcnt)
- mmc_blk_issue_rw_rq(mq, NULL);
- ret = mmc_blk_issue_flush(mq, req);
+ ret = mmc_blk_issue_flush(mq, req, mqrq);
} else {
pr_info("%s: RW rq\n", __func__);
- ret = mmc_blk_issue_rw_rq(mq, req);
+ ret = mmc_blk_issue_rw_rq(mq, mqrq);
}
out:
/* Release host when there are no more requests */
- if (!mq->qcnt)
- mmc_put_card(card);
+ mmc_put_card(card);
pr_info("%s: exit\n", __func__);
return ret;
}
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 5a016ce..e9c9bbf 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -52,15 +52,22 @@ struct mmc_queue_req *mmc_queue_req_find(struct mmc_queue *mq,
struct mmc_queue_req *mqrq;
int i = ffz(mq->qslots);
+ pr_info("%s: enter (%d)\n", __func__, i);
+
+ WARN_ON(i >= mq->qdepth);
if (i >= mq->qdepth)
return NULL;
+//// spin_lock_irq(req->q->queue_lock);
mqrq = &mq->mqrq[i];
WARN_ON(mqrq->req || mq->qcnt >= mq->qdepth ||
test_bit(mqrq->task_id, &mq->qslots));
mqrq->req = req;
mq->qcnt += 1;
__set_bit(mqrq->task_id, &mq->qslots);
+//// spin_unlock_irq(req->q->queue_lock);
+
+ pr_info("%s: exit\n", __func__);
return mqrq;
}
@@ -68,60 +75,17 @@ struct mmc_queue_req *mmc_queue_req_find(struct mmc_queue *mq,
void mmc_queue_req_free(struct mmc_queue *mq,
struct mmc_queue_req *mqrq)
{
+ struct request *req;
+ pr_info("%s: enter\n", __func__);
+ req = mqrq->req;
+ spin_lock_irq(req->q->queue_lock);
WARN_ON(!mqrq->req || mq->qcnt < 1 ||
!test_bit(mqrq->task_id, &mq->qslots));
mqrq->req = NULL;
mq->qcnt -= 1;
__clear_bit(mqrq->task_id, &mq->qslots);
-}
-
-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;
-
- down(&mq->thread_sem);
- do {
- struct request *req;
-
- 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->qcnt)
- cntx->is_waiting_last_req = true;
- else
- mq->asleep = true;
- }
- spin_unlock_irq(q->queue_lock);
-
- if (req || mq->qcnt) {
- set_current_state(TASK_RUNNING);
- mq->issue_fn(mq, req);
- cond_resched();
- } else {
- if (kthread_should_stop()) {
- set_current_state(TASK_RUNNING);
- break;
- }
- up(&mq->thread_sem);
- schedule();
- down(&mq->thread_sem);
- }
- } while (1);
- up(&mq->thread_sem);
-
- return 0;
+ spin_unlock_irq(req->q->queue_lock);
+ pr_info("%s: exit\n", __func__);
}
/*
@@ -134,7 +98,7 @@ static void mmc_request_fn(struct request_queue *q)
{
struct mmc_queue *mq = q->queuedata;
struct request *req;
- struct mmc_context_info *cntx;
+ struct mmc_queue_req *mqrq_cur = NULL;
if (!mq) {
while ((req = blk_fetch_request(q)) != NULL) {
@@ -143,16 +107,28 @@ static void mmc_request_fn(struct request_queue *q)
}
return;
}
-
- cntx = &mq->card->host->context_info;
-
- if (cntx->is_waiting_last_req) {
- cntx->is_new_req = true;
- wake_up_interruptible(&cntx->wait);
+repeat:
+ req = blk_fetch_request(q);
+ if (req && req->cmd_type == REQ_TYPE_FS) {
+ mqrq_cur = mmc_queue_req_find(mq, req);
+ if (!mqrq_cur) {
+ pr_info("%s: command already queued (%d)\n", __func__, mq->qcnt);
+// WARN_ON(1);
+// spin_unlock_irq(q->queue_lock);
+ blk_requeue_request(mq->queue, req);
+// spin_lock_irq(q->queue_lock);
+ req = NULL;
+ }
}
-
- if (mq->asleep)
- wake_up_process(mq->thread);
+ if (!req) {
+ pr_info("%s: no request\n", __func__);
+ return;
+ }
+ spin_unlock_irq(q->queue_lock);
+ mq->issue_fn(mq, req, mqrq_cur);
+ spin_lock_irq(q->queue_lock);
+ goto repeat;
+//#endif
}
static struct scatterlist *mmc_alloc_sg(int sg_len, int *err)
@@ -305,7 +281,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
if (!mq->queue)
return -ENOMEM;
- mq->qdepth = 2;
+ mq->qdepth = 1;
mq->mqrq = mmc_queue_alloc_mqrqs(mq, mq->qdepth);
if (!mq->mqrq)
goto blk_cleanup;
@@ -357,16 +333,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
goto cleanup_queue;
}
- sema_init(&mq->thread_sem, 1);
-
- mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s",
- host->index, subname ? subname : "");
-
- if (IS_ERR(mq->thread)) {
- ret = PTR_ERR(mq->thread);
- goto cleanup_queue;
- }
-
return 0;
cleanup_queue:
@@ -386,9 +352,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
/* Make sure the queue isn't suspended, as that will deadlock */
mmc_queue_resume(mq);
- /* Then terminate our worker thread */
- kthread_stop(mq->thread);
-
/* Empty the queue */
spin_lock_irqsave(q->queue_lock, flags);
q->queuedata = NULL;
@@ -468,8 +431,6 @@ void mmc_queue_suspend(struct mmc_queue *mq)
spin_lock_irqsave(q->queue_lock, flags);
blk_stop_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
-
- down(&mq->thread_sem);
}
}
@@ -485,8 +446,6 @@ void mmc_queue_resume(struct mmc_queue *mq)
if (mq->flags & MMC_QUEUE_SUSPENDED) {
mq->flags &= ~MMC_QUEUE_SUSPENDED;
- up(&mq->thread_sem);
-
spin_lock_irqsave(q->queue_lock, flags);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 1afd5da..c52fa88 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -47,13 +47,10 @@ struct mmc_queue_req {
struct mmc_queue {
struct mmc_card *card;
- struct task_struct *thread;
- struct semaphore thread_sem;
unsigned int flags;
#define MMC_QUEUE_SUSPENDED (1 << 0)
- bool asleep;
- int (*issue_fn)(struct mmc_queue *, struct request *);
+ int (*issue_fn)(struct mmc_queue *, struct request *, struct mmc_queue_req *mqrq);
void *data;
struct request_queue *queue;
struct mmc_queue_req *mqrq;
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index c64266f..949e569 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -346,8 +346,6 @@ int mmc_add_card(struct mmc_card *card)
#ifdef CONFIG_DEBUG_FS
mmc_add_card_debugfs(card);
#endif
- mmc_init_context_info(card->host);
-
card->dev.of_node = mmc_of_find_child_device(card->host, 0);
device_enable_async_suspend(&card->dev);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d2d8d9b..7496c22 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -29,6 +29,7 @@
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/kernel.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -44,6 +45,7 @@
#include "host.h"
#include "sdio_bus.h"
#include "pwrseq.h"
+#include "../card/queue.h"
#include "mmc_ops.h"
#include "sd_ops.h"
@@ -407,19 +409,11 @@ out:
EXPORT_SYMBOL(mmc_start_bkops);
/*
- * mmc_wait_data_done() - done callback for data request
- * @mrq: done data request
+ * mmc_wait_done() - done callback for request
+ * @mrq: done request
*
* Wakes up mmc context, passed as a callback to host controller driver
*/
-static void mmc_wait_data_done(struct mmc_request *mrq)
-{
- struct mmc_context_info *context_info = &mrq->host->context_info;
-
- context_info->is_done_rcv = true;
- wake_up_interruptible(&context_info->wait);
-}
-
static void mmc_wait_done(struct mmc_request *mrq)
{
complete(&mrq->completion);
@@ -438,36 +432,15 @@ static inline void mmc_wait_ongoing_tfr_cmd(struct mmc_host *host)
}
/*
- *__mmc_start_data_req() - starts data request
+ *__mmc_start_req() - starts request
* @host: MMC host to start the request
- * @mrq: data request to start
+ * @mrq: request to start
*
* Sets the done callback to be called when request is completed by the card.
- * Starts data mmc request execution
+ * Starts mmc request execution
* If an ongoing transfer is already in progress, wait for the command line
* to become available before sending another command.
*/
-static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq)
-{
- int err;
-
- mmc_wait_ongoing_tfr_cmd(host);
-
- mrq->done = mmc_wait_data_done;
- mrq->host = host;
-
- init_completion(&mrq->cmd_completion);
-
- err = mmc_start_request(host, mrq);
- if (err) {
- mrq->cmd->error = err;
- mmc_complete_cmd(mrq);
- mmc_wait_data_done(mrq);
- }
-
- return err;
-}
-
static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
{
int err;
@@ -478,6 +451,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
init_completion(&mrq->completion);
mrq->done = mmc_wait_done;
+ mrq->host = host;
init_completion(&mrq->cmd_completion);
@@ -485,7 +459,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
if (err) {
mrq->cmd->error = err;
mmc_complete_cmd(mrq);
- complete(&mrq->completion);
+ mmc_wait_done(mrq);
}
pr_info("%s: exit\n", __func__);
@@ -508,21 +482,17 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
struct mmc_request *mrq,
struct mmc_async_req *next_req)
{
+ struct mmc_queue_req *mq_mrq = container_of(next_req, struct mmc_queue_req,
+ mmc_active);
struct mmc_command *cmd;
- struct mmc_context_info *context_info = &host->context_info;
int err;
pr_info("%s: enter\n", __func__);
while (1) {
- wait_event_interruptible(context_info->wait,
-// context_info->is_done_rcv);
- (context_info->is_done_rcv ||
- context_info->is_new_req));
+ wait_for_completion(&mrq->completion);
pr_info("%s: waiting done\n", __func__);
- context_info->is_waiting_last_req = false;
- if (context_info->is_done_rcv) {
- context_info->is_done_rcv = false;
+ if (1) {
cmd = mrq->cmd;
if (!cmd->error || !cmd->retries ||
@@ -540,11 +510,6 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
__mmc_start_request(host, mrq);
continue; /* wait for done/new event again */
}
- } else if (context_info->is_new_req) {
- if (!next_req) {
- pr_info("%s: exit (!next_req)\n", __func__);
- return MMC_BLK_NEW_REQUEST;
- }
}
}
mmc_retune_release(host);
@@ -614,10 +579,7 @@ EXPORT_SYMBOL(mmc_wait_for_req_done);
*/
bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq)
{
- if (host->areq)
- return host->context_info.is_done_rcv;
- else
- return completion_done(&mrq->completion);
+ return completion_done(&mrq->completion);
}
EXPORT_SYMBOL(mmc_is_req_done);
@@ -688,18 +650,12 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
mmc_pre_req(host, areq->mrq, !host->areq);
}
+ if (areq) //
+ start_err = __mmc_start_req(host, areq->mrq); //
+
+ host->areq = areq; //
if (host->areq) {
err = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);
- if (err == MMC_BLK_NEW_REQUEST) {
- if (error)
- *error = err;
- /*
- * The previous request was not completed,
- * nothing to return
- */
- pr_info("%s: exit (NULL)\n", __func__);
- return NULL;
- }
/*
* Check BKOPS urgency for each R1 response
*/
@@ -720,24 +676,14 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
}
}
- if (!err && areq)
- start_err = __mmc_start_data_req(host, areq->mrq);
-
if (host->areq) {
host->areq->pre_req_done = false;
mmc_post_req(host, host->areq->mrq, 0);
}
- /* Cancel a prepared request if it was not started. */
- if ((err || start_err) && areq) {
- areq->pre_req_done = false;
- mmc_post_req(host, areq->mrq, -EINVAL);
- }
- if (err)
- host->areq = NULL;
- else
- host->areq = areq;
+ data = host->areq; //
+ host->areq = NULL; //
if (error)
*error = err;
@@ -2960,22 +2906,6 @@ void mmc_unregister_pm_notifier(struct mmc_host *host)
}
#endif
-/**
- * mmc_init_context_info() - init synchronization context
- * @host: mmc host
- *
- * Init struct context_info needed to implement asynchronous
- * request mechanism, used by mmc core, host driver and mmc requests
- * supplier.
- */
-void mmc_init_context_info(struct mmc_host *host)
-{
- host->context_info.is_new_req = false;
- host->context_info.is_done_rcv = false;
- host->context_info.is_waiting_last_req = false;
- init_waitqueue_head(&host->context_info.wait);
-}
-
static int __init mmc_init(void)
{
int ret;
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 0fa86a2..34e664b 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -84,8 +84,6 @@ void mmc_remove_host_debugfs(struct mmc_host *host);
void mmc_add_card_debugfs(struct mmc_card *card);
void mmc_remove_card_debugfs(struct mmc_card *card);
-void mmc_init_context_info(struct mmc_host *host);
-
int mmc_execute_tuning(struct mmc_card *card);
int mmc_hs200_to_hs400(struct mmc_card *card);
int mmc_hs400_to_hs200(struct mmc_card *card);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 3d7434e..810f318 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,6 @@ enum mmc_blk_status {
MMC_BLK_DATA_ERR,
MMC_BLK_ECC_ERR,
MMC_BLK_NOMEDIUM,
- MMC_BLK_NEW_REQUEST,
};
/* The number of MMC physical partitions. These consist of:
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9fb00b7..1a46cbd 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -193,20 +193,6 @@ struct mmc_slot {
void *handler_priv;
};
-/**
- * mmc_context_info - synchronization details for mmc context
- * @is_done_rcv wake up reason was done request
- * @is_new_req wake up reason was new request
- * @is_waiting_last_req mmc context waiting for single running request
- * @wait wait queue
- */
-struct mmc_context_info {
- bool is_done_rcv;
- bool is_new_req;
- bool is_waiting_last_req;
- wait_queue_head_t wait;
-};
-
struct regulator;
struct mmc_pwrseq;
@@ -380,7 +366,6 @@ struct mmc_host {
struct dentry *debugfs_root;
struct mmc_async_req *areq; /* active async req */
- struct mmc_context_info context_info; /* async synchronization info */
/* Ongoing data transfer that allows commands during transfer */
struct mmc_request *ongoing_mrq;
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:00 +0200 |
| Subject | [PATCH PoC 6/7] mmc-mq: initial blk-mq support |
| Message-ID | <skcHF-74T-45@gated-at.bofh.it> |
| In reply to | #1488901 |
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
drivers/mmc/card/block.c | 15 +++++----
drivers/mmc/card/queue.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++--
drivers/mmc/card/queue.h | 3 ++
drivers/mmc/core/core.c | 7 ++--
4 files changed, 98 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index ef230e8..9968623 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/kdev_t.h>
+#include <linux/blk-mq.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
@@ -1235,7 +1236,7 @@ out:
mmc_blk_reset_success(md, type);
mmc_put_card(card);
mmc_queue_req_free(mq, mqrq);
- blk_end_request(req, err, blk_rq_bytes(req));
+ blk_mq_end_request(req, err);
return err ? 0 : 1;
}
@@ -1304,7 +1305,7 @@ out_retry:
out:
mmc_put_card(card);
mmc_queue_req_free(mq, mqrq);
- blk_end_request(req, err, blk_rq_bytes(req));
+ blk_mq_end_request(req, err);
return err ? 0 : 1;
}
@@ -1321,16 +1322,14 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req, struct
mmc_put_card(card);
mmc_queue_req_free(mq, mqrq);
- blk_end_request_all(req, ret);
+ blk_mq_end_request(req, ret);
return ret ? 0 : 1;
}
static void mmc_blk_requeue(struct request_queue *q, struct request *req)
{
- spin_lock_irq(q->queue_lock);
- blk_requeue_request(q, req);
- spin_unlock_irq(q->queue_lock);
+ blk_mq_requeue_request(req);
}
/*
@@ -2219,12 +2218,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req, struct mm
/* claim host only for the first request */
mmc_get_card(card);
+ blk_mq_start_request(req);
+
// pr_info("%s: mmc_blk_part_switch (mq=%p md=%p)\n", __func__, mq, md);
ret = mmc_blk_part_switch(card, md);
if (ret) {
if (req) {
mmc_queue_req_free(req->q->queuedata, mqrq); //
- blk_end_request_all(req, -EIO);
+ blk_mq_end_request(req, -EIO);
}
ret = 0;
goto out;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index d4f4859..038c01e 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -11,6 +11,7 @@
*/
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/blk-mq.h>
#include <linux/blkdev.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
@@ -280,6 +281,59 @@ static void mmc_queue_reqs_free_bufs(struct mmc_queue *mq)
mmc_queue_req_free_bufs(&mq->mqrq[i]);
}
+static int mmc_init_request(void *data, struct request *rq,
+ unsigned int hctx_idx, unsigned int request_idx,
+ unsigned int numa_node)
+{
+// struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
+
+// cmd->sense_buffer = kzalloc_node(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL,
+// numa_node);
+// if (!cmd->sense_buffer)
+// return -ENOMEM;
+ return 0;
+}
+
+static void mmc_exit_request(void *data, struct request *rq,
+ unsigned int hctx_idx, unsigned int request_idx)
+{
+// struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
+
+// kfree(cmd->sense_buffer);
+}
+
+static int mmc_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *bd)
+{
+ struct request *req = bd->rq;
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ struct mmc_queue_req *mqrq_cur;
+// struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
+ int ret;
+
+ WARN_ON(req && req->cmd_type != REQ_TYPE_FS);
+
+ if (!mmc_queue_ready(q, mq))
+ return BLK_MQ_RQ_QUEUE_BUSY;
+
+ mqrq_cur = mmc_queue_req_find(mq, req);
+ BUG_ON(!mqrq_cur);
+ mq->issue_fn(mq, req, mqrq_cur);
+
+ return BLK_MQ_RQ_QUEUE_OK;
+}
+
+static struct blk_mq_ops mmc_mq_ops = {
+ .map_queue = blk_mq_map_queue,
+ .queue_rq = mmc_queue_rq,
+// .complete = scsi_softirq_done,
+// .timeout = scsi_timeout,
+ .init_request = mmc_init_request,
+ .exit_request = mmc_exit_request,
+};
+
+
/**
* mmc_init_queue - initialise a queue structure.
* @mq: mmc queue
@@ -293,6 +347,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
spinlock_t *lock, const char *subname)
{
struct mmc_host *host = card->host;
+ struct request_queue *q;
u64 limit = BLK_BOUNCE_HIGH;
bool bounce = false;
int ret = -ENOMEM;
@@ -301,9 +356,28 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
mq->card = card;
- mq->queue = blk_init_queue(mmc_request_fn, lock);
- if (!mq->queue)
- return -ENOMEM;
+// mq->queue = blk_init_queue(mmc_request_fn, lock);
+// if (!mq->queue)
+// return -ENOMEM;
+ memset(&mq->tag_set, 0, sizeof(mq->tag_set));
+ mq->tag_set.ops = &mmc_mq_ops;
+ mq->tag_set.queue_depth = 1;
+ mq->tag_set.numa_node = NUMA_NO_NODE;
+ mq->tag_set.flags =
+ BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE;
+ mq->tag_set.nr_hw_queues = 1;
+ mq->tag_set.cmd_size = sizeof(struct mmc_queue_req);
+
+ ret = blk_mq_alloc_tag_set(&mq->tag_set);
+ if (ret)
+ goto out;
+
+ q = blk_mq_init_queue(&mq->tag_set);
+ if (IS_ERR(q)) {
+ ret = PTR_ERR(q);
+ goto cleanup_tag_set;
+ }
+ mq->queue = q;
mq->qdepth = 1;
mq->mqrq = mmc_queue_alloc_mqrqs(mq, mq->qdepth);
@@ -366,6 +440,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
mq->mqrq = NULL;
blk_cleanup:
blk_cleanup_queue(mq->queue);
+cleanup_tag_set:
+ blk_mq_free_tag_set(&mq->tag_set);
+out:
return ret;
}
@@ -387,6 +464,8 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
kfree(mq->mqrq);
mq->mqrq = NULL;
+ blk_mq_free_tag_set(&mq->tag_set);
+
mq->card = NULL;
}
EXPORT_SYMBOL(mmc_cleanup_queue);
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 20399e4..b67ac83 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -63,6 +63,9 @@ struct mmc_queue {
int testtag;
atomic_t device_busy;
+
+ /* Block layer tags. */
+ struct blk_mq_tag_set tag_set;
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 549e65e..64687f1 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/kernel.h>
+#include <linux/blk-mq.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -489,8 +490,10 @@ BUG_ON(mq_rq && (mq_rq->req->cmd_type == REQ_TYPE_FS) && (mq_rq->req->cmd_flags
mmc_put_card(host->card);
// pr_info("%s: freeing mqrq\n", __func__); //
mmc_queue_req_free(req->q->queuedata, mq_rq); //
- ret = blk_end_request(req, 0, bytes);
-
+// ret = blk_end_request(req, 0, bytes);
+ ret = blk_update_request(req, 0, bytes);
+ if (!ret)
+ __blk_mq_end_request(req, 0);
}
//out:
// pr_info("%s: exit (err=%d, ret=%d)\n", __func__, err, ret);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:00 +0200 |
| Subject | [PATCH PoC 5/7] mmc-mq: remove some debug printks |
| Message-ID | <skcHF-74T-51@gated-at.bofh.it> |
| In reply to | #1488901 |
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
drivers/mmc/card/block.c | 16 ++++++++--------
drivers/mmc/card/queue.c | 12 ++++++------
drivers/mmc/core/core.c | 45 +++++++++++++++++++++++----------------------
3 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 3c2bdc2..ef230e8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2008,7 +2008,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct mmc_queue_req *mqrq)
const u8 packed_nr = 2;
u8 reqs = 0;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
mqrq_cur = mqrq;
rqc = mqrq_cur->req;
@@ -2166,7 +2166,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct mmc_queue_req *mqrq)
#endif
} while (ret);
- pr_info("%s: exit (1==ok)\n", __func__);
+// pr_info("%s: exit (1==ok)\n", __func__);
return 1;
cmd_abort:
@@ -2212,14 +2212,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req, struct mm
struct mmc_card *card = md->queue.card;
unsigned int cmd_flags = req ? req->cmd_flags : 0;
- pr_info("%s: enter (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: enter (mq=%p md=%p)\n", __func__, mq, md);
BUG_ON(!req);
/* claim host only for the first request */
mmc_get_card(card);
- pr_info("%s: mmc_blk_part_switch (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: mmc_blk_part_switch (mq=%p md=%p)\n", __func__, mq, md);
ret = mmc_blk_part_switch(card, md);
if (ret) {
if (req) {
@@ -2231,23 +2231,23 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req, struct mm
}
if (cmd_flags & REQ_DISCARD) {
- pr_info("%s: DISCARD rq (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: DISCARD rq (mq=%p md=%p)\n", __func__, mq, md);
if (req->cmd_flags & REQ_SECURE)
ret = mmc_blk_issue_secdiscard_rq(mq, req, mqrq);
else
ret = mmc_blk_issue_discard_rq(mq, req, mqrq);
} else if (cmd_flags & REQ_FLUSH) {
- pr_info("%s: FLUSH rq (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: FLUSH rq (mq=%p md=%p)\n", __func__, mq, md);
ret = mmc_blk_issue_flush(mq, req, mqrq);
} else {
- pr_info("%s: RW rq (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: RW rq (mq=%p md=%p)\n", __func__, mq, md);
ret = mmc_blk_issue_rw_rq(mq, mqrq);
}
out:
/* Release host when there are no more requests */
///// mmc_put_card(card);
- pr_info("%s: exit (mq=%p md=%p)\n", __func__, mq, md);
+// pr_info("%s: exit (mq=%p md=%p)\n", __func__, mq, md);
return ret;
}
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 3ed4477..d4f4859 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -67,7 +67,7 @@ struct mmc_queue_req *mmc_queue_req_find(struct mmc_queue *mq,
struct mmc_queue_req *mqrq;
int i = ffz(mq->qslots);
- pr_info("%s: enter (%d) (testtag=%d qdepth=%d 0.testtag=%d\n", __func__, i, mq->testtag, mq->qdepth, mq->mqrq[0].testtag);
+// pr_info("%s: enter (%d) (testtag=%d qdepth=%d 0.testtag=%d\n", __func__, i, mq->testtag, mq->qdepth, mq->mqrq[0].testtag);
WARN_ON(mq->testtag == 0);
////// WARN_ON(i >= mq->qdepth);
@@ -85,7 +85,7 @@ struct mmc_queue_req *mmc_queue_req_find(struct mmc_queue *mq,
__set_bit(mqrq->task_id, &mq->qslots);
//// spin_unlock_irq(req->q->queue_lock);
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
return mqrq;
}
@@ -94,7 +94,7 @@ void mmc_queue_req_free(struct mmc_queue *mq,
struct mmc_queue_req *mqrq)
{
struct request *req;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
req = mqrq->req;
//// spin_lock_irq(req->q->queue_lock);
WARN_ON(!mqrq->req || mq->qcnt < 1 ||
@@ -104,7 +104,7 @@ void mmc_queue_req_free(struct mmc_queue *mq,
__clear_bit(mqrq->task_id, &mq->qslots);
//// spin_unlock_irq(req->q->queue_lock);
atomic_dec(&mq->device_busy);
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
}
/*
@@ -132,7 +132,7 @@ repeat:
if (req && req->cmd_type == REQ_TYPE_FS) {
if (mmc_queue_ready(q, mq)) {
} else {
- pr_info("%s: command already queued\n", __func__);
+// pr_info("%s: command already queued\n", __func__);
// WARN_ON(1);
// spin_unlock_irq(q->queue_lock);
blk_requeue_request(mq->queue, req);
@@ -141,7 +141,7 @@ repeat:
}
}
if (!req) {
- pr_info("%s: no request\n", __func__);
+// pr_info("%s: no request\n", __func__);
return;
}
spin_unlock_irq(q->queue_lock);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 22052f0..549e65e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -221,7 +221,7 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{
int err;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
/* Assumes host controller has been runtime resumed by mmc_claim_host */
err = mmc_retune(host);
@@ -264,7 +264,7 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
host->ops->request(host, mrq);
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
}
static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
@@ -273,7 +273,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
unsigned int i, sz;
struct scatterlist *sg;
#endif
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
mmc_retune_hold(host);
if (mmc_card_removed(host->card))
@@ -337,7 +337,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
led_trigger_event(host->led, LED_FULL);
__mmc_start_request(host, mrq);
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
return 0;
}
@@ -431,10 +431,10 @@ static void mmc_wait_done(struct mmc_request *mrq)
struct mmc_command *cmd;
int err = 0, ret = 0;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
cmd = mrq->cmd;
- pr_info("%s: cmd->opcode=%d mq_rq=%p\n", __func__, cmd->opcode, mq_rq);
+// pr_info("%s: cmd->opcode=%d mq_rq=%p\n", __func__, cmd->opcode, mq_rq);
if (mq_rq)
areq = &mq_rq->mmc_active;
@@ -457,7 +457,8 @@ static void mmc_wait_done(struct mmc_request *mrq)
cmd->retries--;
cmd->error = 0;
__mmc_start_request(host, mrq);
- goto out;
+// goto out;
+ return;
}
mmc_retune_release(host);
@@ -486,13 +487,13 @@ BUG_ON(mq_rq && (mq_rq->req->cmd_type == REQ_TYPE_FS) && (mq_rq->req->cmd_flags
bytes = brq->data.bytes_xfered;
mmc_put_card(host->card);
- pr_info("%s: freeing mqrq\n", __func__); //
+// pr_info("%s: freeing mqrq\n", __func__); //
mmc_queue_req_free(req->q->queuedata, mq_rq); //
ret = blk_end_request(req, 0, bytes);
}
-out:
- pr_info("%s: exit (err=%d, ret=%d)\n", __func__, err, ret);
+//out:
+// pr_info("%s: exit (err=%d, ret=%d)\n", __func__, err, ret);
}
static inline void mmc_wait_ongoing_tfr_cmd(struct mmc_host *host)
@@ -521,7 +522,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq, struc
{
int err;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
mmc_wait_ongoing_tfr_cmd(host);
@@ -539,7 +540,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq, struc
mmc_wait_done(mrq);
}
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
return err;
}
@@ -717,9 +718,9 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
int start_err = 0;
struct mmc_async_req *data = host->areq;
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
- pr_info("%s: areq=%p host->areq=%p\n", __func__, areq, host->areq);
+// pr_info("%s: areq=%p host->areq=%p\n", __func__, areq, host->areq);
/* Prepare a new request */
// if (areq && !areq->pre_req_done) {
@@ -767,7 +768,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
if (error)
*error = err;
#endif
- pr_info("%s: exit (data=%p)\n", __func__, data);
+// pr_info("%s: exit (data=%p)\n", __func__, data);
return data;
}
EXPORT_SYMBOL(mmc_start_req);
@@ -786,19 +787,19 @@ EXPORT_SYMBOL(mmc_start_req);
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
- pr_info("%s: enter\n", __func__);
+// pr_info("%s: enter\n", __func__);
__mmc_start_req(host, mrq, NULL);
if (!mrq->cap_cmd_during_tfr) {
// mmc_wait_for_req_done(host, mrq);
// BUG(); //
- pr_info("%s: wait start\n", __func__);
+// pr_info("%s: wait start\n", __func__);
wait_for_completion(&mrq->completion);
- pr_info("%s: wait done\n", __func__);
+// pr_info("%s: wait done\n", __func__);
}
- pr_info("%s: exit\n", __func__);
+// pr_info("%s: exit\n", __func__);
}
EXPORT_SYMBOL(mmc_wait_for_req);
@@ -883,7 +884,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
{
struct mmc_request mrq = {NULL};
- pr_info("%s: enter (cmd->opcode=%d retries=%d)\n", __func__, cmd->opcode, cmd->retries);
+// pr_info("%s: enter (cmd->opcode=%d retries=%d)\n", __func__, cmd->opcode, cmd->retries);
WARN_ON(!host->claimed);
@@ -892,10 +893,10 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
mrq.cmd = cmd;
cmd->data = NULL;
- pr_info("%s: cmd->opcode=%d retries=%d\n", __func__, cmd->opcode, cmd->retries);
+// pr_info("%s: cmd->opcode=%d retries=%d\n", __func__, cmd->opcode, cmd->retries);
mmc_wait_for_req(host, &mrq);
- pr_info("%s: exit (cmd->opcode=%d retries=%d cmd->error=%d)\n", __func__, cmd->opcode, cmd->retries, cmd->error);
+// pr_info("%s: exit (cmd->opcode=%d retries=%d cmd->error=%d)\n", __func__, cmd->opcode, cmd->retries, cmd->error);
return cmd->error;
}
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
|---|---|
| Date | 2016-09-22 16:10 +0200 |
| Subject | [PATCH PoC 4/7] mmc-mq: implement checking for queue busy condition |
| Message-ID | <skcRj-7nx-11@gated-at.bofh.it> |
| In reply to | #1488901 |
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
drivers/mmc/card/queue.c | 28 +++++++++++++++++++++++-----
drivers/mmc/card/queue.h | 2 ++
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 6fd711d..3ed4477 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -46,6 +46,21 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
return BLKPREP_OK;
}
+int mmc_queue_ready(struct request_queue *q, struct mmc_queue *mq)
+{
+ unsigned int busy;
+
+ busy = atomic_inc_return(&mq->device_busy) - 1;
+
+ if (busy >= mq->qdepth)
+ goto out_dec;
+
+ return 1;
+out_dec:
+ atomic_dec(&mq->device_busy);
+ return 0;
+}
+
struct mmc_queue_req *mmc_queue_req_find(struct mmc_queue *mq,
struct request *req)
{
@@ -81,13 +96,14 @@ void mmc_queue_req_free(struct mmc_queue *mq,
struct request *req;
pr_info("%s: enter\n", __func__);
req = mqrq->req;
- spin_lock_irq(req->q->queue_lock);
+//// spin_lock_irq(req->q->queue_lock);
WARN_ON(!mqrq->req || mq->qcnt < 1 ||
!test_bit(mqrq->task_id, &mq->qslots));
mqrq->req = NULL;
mq->qcnt -= 1;
__clear_bit(mqrq->task_id, &mq->qslots);
- spin_unlock_irq(req->q->queue_lock);
+//// spin_unlock_irq(req->q->queue_lock);
+ atomic_dec(&mq->device_busy);
pr_info("%s: exit\n", __func__);
}
@@ -114,9 +130,9 @@ repeat:
req = blk_fetch_request(q);
WARN_ON(req && req->cmd_type != REQ_TYPE_FS);
if (req && req->cmd_type == REQ_TYPE_FS) {
- mqrq_cur = mmc_queue_req_find(mq, req);
- if (!mqrq_cur) {
- pr_info("%s: command already queued (%d)\n", __func__, mq->qcnt);
+ if (mmc_queue_ready(q, mq)) {
+ } else {
+ pr_info("%s: command already queued\n", __func__);
// WARN_ON(1);
// spin_unlock_irq(q->queue_lock);
blk_requeue_request(mq->queue, req);
@@ -129,6 +145,8 @@ repeat:
return;
}
spin_unlock_irq(q->queue_lock);
+ mqrq_cur = mmc_queue_req_find(mq, req);
+ BUG_ON(!mqrq_cur);
mq->issue_fn(mq, req, mqrq_cur);
spin_lock_irq(q->queue_lock);
goto repeat;
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 3adf1bc..20399e4 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -61,6 +61,8 @@ struct mmc_queue {
unsigned long qslots;
int testtag;
+
+ atomic_t device_busy;
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web