diff options
author | Carsten Emde <C.Emde@osadl.org> | 2011-09-21 04:22:11 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-09-21 04:22:11 -0400 |
commit | 6c4867f6469964e34c5f4ee229a2a7f71a34c7ff (patch) | |
tree | 639fb854b56d746aeb324011372b4c0571fd01ef | |
parent | d11bb4462c4cc6ddd45c6927c617ad79fa6fb8fc (diff) |
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: Carsten Emde <C.Emde@osadl.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/floppy.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 98de8f418676..9955a53733b2 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4250,7 +4250,7 @@ static int __init floppy_init(void) | |||
4250 | use_virtual_dma = can_use_virtual_dma & 1; | 4250 | use_virtual_dma = can_use_virtual_dma & 1; |
4251 | fdc_state[0].address = FDC1; | 4251 | fdc_state[0].address = FDC1; |
4252 | if (fdc_state[0].address == -1) { | 4252 | if (fdc_state[0].address == -1) { |
4253 | del_timer(&fd_timeout); | 4253 | del_timer_sync(&fd_timeout); |
4254 | err = -ENODEV; | 4254 | err = -ENODEV; |
4255 | goto out_unreg_region; | 4255 | goto out_unreg_region; |
4256 | } | 4256 | } |
@@ -4261,7 +4261,7 @@ static int __init floppy_init(void) | |||
4261 | fdc = 0; /* reset fdc in case of unexpected interrupt */ | 4261 | fdc = 0; /* reset fdc in case of unexpected interrupt */ |
4262 | err = floppy_grab_irq_and_dma(); | 4262 | err = floppy_grab_irq_and_dma(); |
4263 | if (err) { | 4263 | if (err) { |
4264 | del_timer(&fd_timeout); | 4264 | del_timer_sync(&fd_timeout); |
4265 | err = -EBUSY; | 4265 | err = -EBUSY; |
4266 | goto out_unreg_region; | 4266 | goto out_unreg_region; |
4267 | } | 4267 | } |
@@ -4318,7 +4318,7 @@ static int __init floppy_init(void) | |||
4318 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); | 4318 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); |
4319 | } | 4319 | } |
4320 | fdc = 0; | 4320 | fdc = 0; |
4321 | del_timer(&fd_timeout); | 4321 | del_timer_sync(&fd_timeout); |
4322 | current_drive = 0; | 4322 | current_drive = 0; |
4323 | initialized = true; | 4323 | initialized = true; |
4324 | if (have_no_fdc) { | 4324 | if (have_no_fdc) { |
@@ -4368,7 +4368,7 @@ out_unreg_blkdev: | |||
4368 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4368 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
4369 | out_put_disk: | 4369 | out_put_disk: |
4370 | while (dr--) { | 4370 | while (dr--) { |
4371 | del_timer(&motor_off_timer[dr]); | 4371 | del_timer_sync(&motor_off_timer[dr]); |
4372 | if (disks[dr]->queue) | 4372 | if (disks[dr]->queue) |
4373 | blk_cleanup_queue(disks[dr]->queue); | 4373 | blk_cleanup_queue(disks[dr]->queue); |
4374 | put_disk(disks[dr]); | 4374 | put_disk(disks[dr]); |