aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cfq-iosched.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-06-27 08:49:39 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-27 17:33:30 -0400
commit96c51ce94e8415d2dfb08358bbd50e1589111f33 (patch)
treeb1b049dce9f3013334ddca6019e5835c4c994ae6 /drivers/block/cfq-iosched.c
parent52a5e15f665385ac99607d6b9e0c3dbdf17c5cfa (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>
Diffstat (limited to 'drivers/block/cfq-iosched.c')
-rw-r--r--drivers/block/cfq-iosched.c5
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);