Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -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)
	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)
		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)
	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]);