diff options
author | Tejun Heo <tj@kernel.org> | 2011-10-19 14:32:38 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-10-19 14:32:38 +0200 |
commit | e3c78ca524d230bc145e902625e88c392a58ddf3 (patch) | |
tree | 833eb544dd4180fd626f60da17788aae7830f4dc /block/blk-core.c | |
parent | 315fceee81155ef2aeed9316ca72aeea9347db5c (diff) |
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.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index a3d2fdc8ed1c..149149dd7f7b 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 |