mmc: add new request stats infrastructure
Add statistics infrastructure for new_request_notification
mechanism. Information about the mechanism is collected by
counters that are located at decision points in the flow
of this feature.
Change-Id: I863911e7ecade609b3b4dff619dd6b059a098fcc
Signed-off-by: Konstantin Dorfman <kdorfman@codeaurora.org>
Signed-off-by: Lee Susman <lsusman@codeaurora.org>
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index c762ed1..7b80dfb 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -59,12 +59,19 @@
struct request_queue *q = mq->queue;
struct request *req;
struct mmc_card *card = mq->card;
+ struct mmc_async_event_stats *stats;
+ struct mmc_queue_req *tmp;
+
+ if (!card)
+ return 0;
+
+ stats = &mq->card->async_event_stats;
current->flags |= PF_MEMALLOC;
down(&mq->thread_sem);
do {
- struct mmc_queue_req *tmp;
+
req = NULL; /* Must be set to NULL at each iteration */
spin_lock_irq(q->queue_lock);
@@ -74,9 +81,11 @@
if (!req && mq->mqrq_prev->req &&
!(mq->mqrq_prev->req->cmd_flags & REQ_SANITIZE) &&
!(mq->mqrq_prev->req->cmd_flags & REQ_FLUSH) &&
- !(mq->mqrq_prev->req->cmd_flags & REQ_DISCARD))
+ !(mq->mqrq_prev->req->cmd_flags & REQ_DISCARD)) {
card->host->context_info.is_waiting_last_req = true;
-
+ if (stats && stats->enabled)
+ stats->null_fetched++;
+ }
spin_unlock_irq(q->queue_lock);
if (req || mq->mqrq_prev->req) {
@@ -95,6 +104,8 @@
mq->issue_fn(mq, req);
if (mq->flags & MMC_QUEUE_NEW_REQUEST) {
mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
+ if (stats && stats->enabled)
+ stats->fetch_due_to_new_req++;
continue; /* fetch again */
}
} else {
@@ -129,6 +140,7 @@
static void mmc_request(struct request_queue *q)
{
struct mmc_queue *mq = q->queuedata;
+ struct mmc_async_event_stats *stats;
struct request *req;
unsigned long flags;
struct mmc_context_info *cntx;
@@ -140,22 +152,39 @@
}
return;
}
+ if (mq->card) {
+ cntx = &mq->card->host->context_info;
+ stats = &mq->card->async_event_stats;
+ } else
+ return;
cntx = &mq->card->host->context_info;
+ stats = &mq->card->async_event_stats;
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) {
+ if (stats && stats->enabled)
+ stats->wakeup_new++;
+ if (cntx->is_new_req)
+ if (stats->enabled)
+ stats->new_req_when_new_marked++;
cntx->is_new_req = true;
wake_up_interruptible(&cntx->wait);
- }
+ } else if (stats->enabled)
+ stats->q_no_waiting++;
spin_unlock_irqrestore(&cntx->lock, flags);
- } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
+ } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) {
wake_up_process(mq->thread);
+ if (stats->enabled)
+ stats->wakeup_mq_thread++;
+ } else if (stats->enabled)
+ stats->no_mmc_request_action++;
}
static struct scatterlist *mmc_alloc_sg(int sg_len, int *err)