aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2012-11-06 05:47:13 -0500
committerJens Axboe <axboe@kernel.dk>2012-11-23 08:32:54 -0500
commiteac7cc52c6b410e542af431b2ee93f3d7dbfb6af (patch)
tree3754bb6774c068e8eab2d8d7cb308f829422cfd4 /drivers
parent3d70f8c617a436c7146ecb81df2265b4626dfe89 (diff)
floppy: destroy floppy workqueue before cleaning up the queue
We need to first destroy the floppy_wq workqueue before cleaning up the queue. Otherwise we might race with still pending work with the workqueue, but all the block queue already gone. This might lead to various oopses, such as CPU 0 Pid: 6, comm: kworker/u:0 Not tainted 3.7.0-rc4 #1 Bochs Bochs RIP: 0010:[<ffffffff8134eef5>] [<ffffffff8134eef5>] blk_peek_request+0xd5/0x1c0 RSP: 0000:ffff88000dc7dd88 EFLAGS: 00010092 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ffff88000f602688 RSI: ffffffff81fd95d8 RDI: 6b6b6b6b6b6b6b6b RBP: ffff88000dc7dd98 R08: ffffffff81fd95c8 R09: 0000000000000000 R10: ffffffff81fd9480 R11: 0000000000000001 R12: 6b6b6b6b6b6b6b6b R13: ffff88000dc7dfd8 R14: ffff88000dc7dfd8 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffffffff81e21000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001e11000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/u:0 (pid: 6, threadinfo ffff88000dc7c000, task ffff88000dc5ecc0) Stack: 0000000000000000 0000000000000000 ffff88000dc7ddb8 ffffffff8134efee ffff88000dc7ddb8 0000000000000000 ffff88000dc7dde8 ffffffff814aef3c ffffffff81e75d80 ffff88000dc0c640 ffff88000fbfb000 ffffffff814aed90 Call Trace: [<ffffffff8134efee>] blk_fetch_request+0xe/0x30 [<ffffffff814aef3c>] redo_fd_request+0x1ac/0x400 [<ffffffff814aed90>] ? start_motor+0x130/0x130 [<ffffffff8106b526>] process_one_work+0x136/0x450 [<ffffffff8106af65>] ? manage_workers+0x205/0x2e0 [<ffffffff8106bb6d>] worker_thread+0x14d/0x420 [<ffffffff8106ba20>] ? rescuer_thread+0x1a0/0x1a0 [<ffffffff8107075a>] kthread+0xba/0xc0 [<ffffffff810706a0>] ? __kthread_parkme+0x80/0x80 [<ffffffff818b553a>] ret_from_fork+0x7a/0xb0 [<ffffffff810706a0>] ? __kthread_parkme+0x80/0x80 Code: 0f 84 c0 00 00 00 83 f8 01 0f 85 e2 00 00 00 81 4b 40 00 00 80 00 48 89 df e8 58 f8 ff ff be fb ff ff ff fe ff ff <49> 8b 1c 24 49 39 dc 0f 85 2e ff ff ff 41 0f b6 84 24 28 04 00 RIP [<ffffffff8134eef5>] blk_peek_request+0xd5/0x1c0 RSP <ffff88000dc7dd88> Reported-by: Fengguang Wu <fengguang.wu@intel.com> Tested-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/floppy.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 1c49d7173966..2ddd64a9ffde 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4330,6 +4330,7 @@ out_unreg_region:
4330out_unreg_blkdev: 4330out_unreg_blkdev:
4331 unregister_blkdev(FLOPPY_MAJOR, "fd"); 4331 unregister_blkdev(FLOPPY_MAJOR, "fd");
4332out_put_disk: 4332out_put_disk:
4333 destroy_workqueue(floppy_wq);
4333 for (drive = 0; drive < N_DRIVE; drive++) { 4334 for (drive = 0; drive < N_DRIVE; drive++) {
4334 if (!disks[drive]) 4335 if (!disks[drive])
4335 break; 4336 break;
@@ -4340,7 +4341,6 @@ out_put_disk:
4340 } 4341 }
4341 put_disk(disks[drive]); 4342 put_disk(disks[drive]);
4342 } 4343 }
4343 destroy_workqueue(floppy_wq);
4344 return err; 4344 return err;
4345} 4345}
4346 4346
@@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void)
4555 unregister_blkdev(FLOPPY_MAJOR, "fd"); 4555 unregister_blkdev(FLOPPY_MAJOR, "fd");
4556 platform_driver_unregister(&floppy_driver); 4556 platform_driver_unregister(&floppy_driver);
4557 4557
4558 destroy_workqueue(floppy_wq);
4559
4558 for (drive = 0; drive < N_DRIVE; drive++) { 4560 for (drive = 0; drive < N_DRIVE; drive++) {
4559 del_timer_sync(&motor_off_timer[drive]); 4561 del_timer_sync(&motor_off_timer[drive]);
4560 4562
@@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void)
4578 4580
4579 cancel_delayed_work_sync(&fd_timeout); 4581 cancel_delayed_work_sync(&fd_timeout);
4580 cancel_delayed_work_sync(&fd_timer); 4582 cancel_delayed_work_sync(&fd_timer);
4581 destroy_workqueue(floppy_wq);
4582 4583
4583 if (atomic_read(&usage_count)) 4584 if (atomic_read(&usage_count))
4584 floppy_release_irq_and_dma(); 4585 floppy_release_irq_and_dma();