>From 8ccee6132f376d78bb6e355016ecc06c9ca47b9f Mon Sep 17 00:00:00 2001 From: Jarkko Lavinen Date: Tue, 3 Nov 2009 09:48:00 +0200 Subject: [PATCH] block: Move elevator exit from blk_cleanup_queue() to blk_release_queue() If block_cleanup_queue() should not remove elevator if it is still in use. Better call the elevator exit in blk_release_queue() when all the reference to queue are gone. Since drivers could use queue locks which are freed after returning from blk_cleanup_queue(), switch the queue lock to internal one. Signed-off-by: Jarkko Lavinen --- block/blk-core.c | 8 ++++++-- block/blk-sysfs.c | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 9daf621..8d7d5aa 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -449,6 +449,8 @@ void blk_put_queue(struct request_queue *q) void blk_cleanup_queue(struct request_queue *q) { + spinlock_t *oldlock; + /* * We know we have process context here, so we can be a little * cautious and ensure that pending block actions on this device @@ -461,8 +463,10 @@ void blk_cleanup_queue(struct request_queue *q) queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); mutex_unlock(&q->sysfs_lock); - if (q->elevator) - elevator_exit(q->elevator); + oldlock = q->queue_lock; + spin_lock_irq(oldlock); + q->queue_lock = &q->__queue_lock; + spin_unlock_irq(oldlock); blk_put_queue(q); } diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 21e275d..8ac3e5b 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -304,6 +304,9 @@ static void blk_release_queue(struct kobject *kobj) container_of(kobj, struct request_queue, kobj); struct request_list *rl = &q->rq; + if (q->elevator) + elevator_exit(q->elevator); + blk_sync_queue(q); if (rl->rq_pool) -- 1.6.5