summaryrefslogtreecommitdiff
path: root/block/blk-core.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-10-19 14:32:38 +0200
committerJens Axboe <axboe@kernel.dk>2011-10-19 14:32:38 +0200
commite3c78ca524d230bc145e902625e88c392a58ddf3 (patch)
tree833eb544dd4180fd626f60da17788aae7830f4dc /block/blk-core.c
parent315fceee81155ef2aeed9316ca72aeea9347db5c (diff)
downloadlinux-3.10-e3c78ca524d230bc145e902625e88c392a58ddf3.tar.gz
linux-3.10-e3c78ca524d230bc145e902625e88c392a58ddf3.tar.bz2
linux-3.10-e3c78ca524d230bc145e902625e88c392a58ddf3.zip
block: reorganize queue draining
Reorganize queue draining related code in preparation of queue exit changes. * Factor out actual draining from elv_quiesce_start() to blk_drain_queue(). * Make elv_quiesce_start/end() responsible for their own locking. * Replace open-coded ELVSWITCH clearing in elevator_switch() with elv_quiesce_end(). This patch doesn't cause any visible functional difference. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-core.c')
-rw-r--r--block/blk-core.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index a3d2fdc8ed1..149149dd7f7 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -28,6 +28,7 @@
#include <linux/task_io_accounting_ops.h>
#include <linux/fault-inject.h>
#include <linux/list_sort.h>
+#include <linux/delay.h>
#define CREATE_TRACE_POINTS
#include <trace/events/block.h>
@@ -345,6 +346,33 @@ void blk_put_queue(struct request_queue *q)
}
EXPORT_SYMBOL(blk_put_queue);
+/**
+ * blk_drain_queue - drain requests from request_queue
+ * @q: queue to drain
+ *
+ * Drain ELV_PRIV requests from @q. The caller is responsible for ensuring
+ * that no new requests which need to be drained are queued.
+ */
+void blk_drain_queue(struct request_queue *q)
+{
+ while (true) {
+ int nr_rqs;
+
+ spin_lock_irq(q->queue_lock);
+
+ elv_drain_elevator(q);
+
+ __blk_run_queue(q);
+ nr_rqs = q->rq.elvpriv;
+
+ spin_unlock_irq(q->queue_lock);
+
+ if (!nr_rqs)
+ break;
+ msleep(10);
+ }
+}
+
/*
* Note: If a driver supplied the queue lock, it is disconnected
* by this function. The actual state of the lock doesn't matter