diff options
author | Jens Axboe <axboe@suse.de> | 2005-06-27 08:49:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 17:33:30 -0400 |
commit | 96c51ce94e8415d2dfb08358bbd50e1589111f33 (patch) | |
tree | b1b049dce9f3013334ddca6019e5835c4c994ae6 | |
parent | 52a5e15f665385ac99607d6b9e0c3dbdf17c5cfa (diff) |
[PATCH] CFQ io scheduler: scheduler switch oops
If cfq is managing a queue and a new scheduler is later selected, it is
possible for the cfqd unplug_work work to be queued after the kblockd
work struct has been flushed. The problem is the ordering of
cfq_shutdown_timer_wq() and blk_put_queue() in cfq_put_cfqd(). The
latter may rearm the work, leaving cfq_kick_queue() with dead data.
Signed-off-by: Jens Axboe <axboe@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/block/cfq-iosched.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index 1ecb179b8604..ff1cc968f96d 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c | |||
@@ -2249,10 +2249,11 @@ static void cfq_put_cfqd(struct cfq_data *cfqd) | |||
2249 | if (!atomic_dec_and_test(&cfqd->ref)) | 2249 | if (!atomic_dec_and_test(&cfqd->ref)) |
2250 | return; | 2250 | return; |
2251 | 2251 | ||
2252 | cfq_shutdown_timer_wq(cfqd); | ||
2253 | |||
2254 | blk_put_queue(q); | 2252 | blk_put_queue(q); |
2255 | 2253 | ||
2254 | cfq_shutdown_timer_wq(cfqd); | ||
2255 | q->elevator->elevator_data = NULL; | ||
2256 | |||
2256 | mempool_destroy(cfqd->crq_pool); | 2257 | mempool_destroy(cfqd->crq_pool); |
2257 | kfree(cfqd->crq_hash); | 2258 | kfree(cfqd->crq_hash); |
2258 | kfree(cfqd->cfq_hash); | 2259 | kfree(cfqd->cfq_hash); |