Commit 6c4867f6 authored by Carsten Emde's avatar Carsten Emde Committed by Jens Axboe

floppy: use del_timer_sync() in init cleanup

When no floppy is found the module code can be released while a timer
function is pending or about to be executed.

CPU0                                  CPU1
				      floppy_init()
timer_softirq()
   spin_lock_irq(&base->lock);
   detach_timer();
   spin_unlock_irq(&base->lock);
   -> Interrupt
					del_timer();
				        return -ENODEV;
                                      module_cleanup();
   <- EOI
   call_timer_fn();
   OOPS

Use del_timer_sync() to prevent this.
Signed-off-by: default avatarCarsten Emde <C.Emde@osadl.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d11bb446
...@@ -4250,7 +4250,7 @@ static int __init floppy_init(void) ...@@ -4250,7 +4250,7 @@ static int __init floppy_init(void)
use_virtual_dma = can_use_virtual_dma & 1; use_virtual_dma = can_use_virtual_dma & 1;
fdc_state[0].address = FDC1; fdc_state[0].address = FDC1;
if (fdc_state[0].address == -1) { if (fdc_state[0].address == -1) {
del_timer(&fd_timeout); del_timer_sync(&fd_timeout);
err = -ENODEV; err = -ENODEV;
goto out_unreg_region; goto out_unreg_region;
} }
...@@ -4261,7 +4261,7 @@ static int __init floppy_init(void) ...@@ -4261,7 +4261,7 @@ static int __init floppy_init(void)
fdc = 0; /* reset fdc in case of unexpected interrupt */ fdc = 0; /* reset fdc in case of unexpected interrupt */
err = floppy_grab_irq_and_dma(); err = floppy_grab_irq_and_dma();
if (err) { if (err) {
del_timer(&fd_timeout); del_timer_sync(&fd_timeout);
err = -EBUSY; err = -EBUSY;
goto out_unreg_region; goto out_unreg_region;
} }
...@@ -4318,7 +4318,7 @@ static int __init floppy_init(void) ...@@ -4318,7 +4318,7 @@ static int __init floppy_init(void)
user_reset_fdc(-1, FD_RESET_ALWAYS, false); user_reset_fdc(-1, FD_RESET_ALWAYS, false);
} }
fdc = 0; fdc = 0;
del_timer(&fd_timeout); del_timer_sync(&fd_timeout);
current_drive = 0; current_drive = 0;
initialized = true; initialized = true;
if (have_no_fdc) { if (have_no_fdc) {
...@@ -4368,7 +4368,7 @@ static int __init floppy_init(void) ...@@ -4368,7 +4368,7 @@ static int __init floppy_init(void)
unregister_blkdev(FLOPPY_MAJOR, "fd"); unregister_blkdev(FLOPPY_MAJOR, "fd");
out_put_disk: out_put_disk:
while (dr--) { while (dr--) {
del_timer(&motor_off_timer[dr]); del_timer_sync(&motor_off_timer[dr]);
if (disks[dr]->queue) if (disks[dr]->queue)
blk_cleanup_queue(disks[dr]->queue); blk_cleanup_queue(disks[dr]->queue);
put_disk(disks[dr]); put_disk(disks[dr]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment