mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lin Ming <ming.m.lin@intel.com>
To: Jens Axboe <axboe@kernel.dk>, Alan Stern <stern@rowland.harvard.edu>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	linux-scsi@vger.kernel.org
Subject: [RFC PATCH 3/3] block: add queue idle timer
Date: Tue, 15 May 2012 16:48:17 +0800	[thread overview]
Message-ID: <1337071697-30920-4-git-send-email-ming.m.lin@intel.com> (raw)
In-Reply-To: <1337071697-30920-1-git-send-email-ming.m.lin@intel.com>

Add an idle timer that is set to some suitable timeout and would be
added when the queue first goes empty. If nothing has happened during
the timeout interval, then the queue is suspended.

Queueing a new request could check the state and resume queue if it is
supended.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
 block/blk-core.c       |   25 +++++++++++++++++++++++++
 block/elevator.c       |   10 ++++++++++
 include/linux/blkdev.h |    3 +++
 3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 1f61b74..01b4e14 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -473,6 +473,17 @@ struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(blk_alloc_queue);
 
+static void blk_rq_idle_timer(unsigned long data)
+{
+	struct request_queue *q = (struct request_queue *) data;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	if (!q->nr_pending && q->runtime_pm)
+		q->runtime_pm(q, PMSG_SUSPEND);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
 struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 {
 	struct request_queue *q;
@@ -504,6 +515,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 	setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
 		    laptop_mode_timer_fn, (unsigned long) q);
 	setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
+	setup_timer(&q->idle, blk_rq_idle_timer, (unsigned long) q);
 	INIT_LIST_HEAD(&q->timeout_list);
 	INIT_LIST_HEAD(&q->icq_list);
 	INIT_LIST_HEAD(&q->flush_queue[0]);
@@ -1129,6 +1141,13 @@ void __blk_put_request(struct request_queue *q, struct request *req)
 	if (unlikely(--req->ref_count))
 		return;
 
+	/* PM request is not accounted */
+	if (!(req->cmd_flags & REQ_PM)) {
+		if (!(--q->nr_pending))
+			/* Hard code to 20secs, will move to sysfs */
+			mod_timer(&q->idle, jiffies + 20*HZ);
+	}
+
 	elv_completed_request(q, req);
 
 	/* this is a bio leak */
@@ -1917,6 +1936,12 @@ struct request *blk_peek_request(struct request_queue *q)
 	int ret;
 
 	while ((rq = __elv_next_request(q)) != NULL) {
+		/* Only PM request is allowed to go if the queue is suspended */
+		if (q->pm_status != RPM_ACTIVE && !(rq->cmd_flags & REQ_PM)) {
+			rq = NULL;
+			break;
+		}
+
 		if (!(rq->cmd_flags & REQ_STARTED)) {
 			/*
 			 * This is the first time the device driver
diff --git a/block/elevator.c b/block/elevator.c
index f016855..7e68994 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -546,6 +546,9 @@ void elv_requeue_request(struct request_queue *q, struct request *rq)
 
 	rq->cmd_flags &= ~REQ_STARTED;
 
+	/* __elv_add_request will increment the count */
+	if (!(rq->cmd_flags & REQ_PM))
+		q->nr_pending--;
 	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
@@ -587,6 +590,13 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
 {
 	trace_block_rq_insert(q, rq);
 
+	if (!(rq->cmd_flags & REQ_PM)) {
+		if (!(q->pm_status != RPM_ACTIVE) &&
+				q->nr_pending++ == 0 && q->runtime_pm)
+			/* async resume */
+			q->runtime_pm(q, PMSG_RESUME);
+	}
+
 	rq->q = q;
 
 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index b5b212c..f6bc96b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -347,6 +347,7 @@ struct request_queue {
 	unsigned int		nr_congestion_on;
 	unsigned int		nr_congestion_off;
 	unsigned int		nr_batching;
+	unsigned int		nr_pending;
 
 	int			pm_status;
 
@@ -365,6 +366,8 @@ struct request_queue {
 	struct timer_list	timeout;
 	struct list_head	timeout_list;
 
+	struct timer_list	idle;
+
 	struct list_head	icq_list;
 
 	struct queue_limits	limits;
-- 
1.7.2.5


  parent reply	other threads:[~2012-05-15  8:49 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-15  8:48 [RFC PATCH 0/3] block layer runtime pm Lin Ming
2012-05-15  8:48 ` [RFC PATCH 1/3] block: add a flag to identify PM request Lin Ming
2012-05-15 14:35   ` Alan Stern
2012-05-15 15:33     ` Lin Ming
2012-05-15 15:37       ` Alan Cox
2012-05-15 15:58         ` Lin Ming
2012-05-15 18:30           ` Alan Stern
2012-05-15 16:03       ` Alan Stern
2012-05-15  8:48 ` [RFC PATCH 2/3] block: add queue runtime pm callback Lin Ming
2012-05-15 14:37   ` Alan Stern
2012-05-15 15:36     ` Lin Ming
2012-05-15  8:48 ` Lin Ming [this message]
2012-05-15 14:39   ` [RFC PATCH 3/3] block: add queue idle timer Alan Stern
2012-05-15 15:49     ` Lin Ming
2012-05-15 19:19   ` Jeff Moyer
2012-05-16  1:27     ` Lin Ming
2012-05-16 13:04       ` Jeff Moyer
2012-05-16 13:53         ` Jens Axboe
2012-05-16 14:28           ` Alan Stern
2012-05-16 15:40           ` Lin Ming
2012-05-16 15:59             ` Alan Stern
2012-05-16 16:12               ` Lin Ming
2012-05-16 18:29               ` Jens Axboe

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=1337071697-30920-4-git-send-email-ming.m.lin@intel.com \
    --to=ming.m.lin@intel.com \
    --cc=axboe@kernel.dk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /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

Powered by JetHome