linux/drivers/media/rc
James Hogan ac03086067 [media] img-ir/hw: Fix potential deadlock stopping timer
The end timer is used for switching back from repeat code timings when
no repeat codes have been received for a certain amount of time. When
the protocol is changed, the end timer is deleted synchronously with
del_timer_sync(), however this takes place while holding the main spin
lock, and the timer handler also needs to acquire the spin lock.

This opens the possibility of a deadlock on an SMP system if the
protocol is changed just as the repeat timer is expiring. One CPU could
end up in img_ir_set_decoder() holding the lock and waiting for the end
timer to complete, while the other CPU is stuck in the timer handler
spinning on the lock held by the first CPU.

Lockdep also spots a possible lock inversion in the same code, since
img_ir_set_decoder() acquires the img-ir lock before the timer lock, but
the timer handler will try and acquire them the other way around:

=========================================================
[ INFO: possible irq lock inversion dependency detected ]
3.18.0-rc5+ #957 Not tainted
---------------------------------------------------------
swapper/0/0 just changed the state of lock:
 (((&hw->end_timer))){+.-...}, at: [<4006ae5c>] _call_timer_fn+0x0/0xfc
but this lock was taken by another, HARDIRQ-safe lock in the past:
 (&(&priv->lock)->rlock#2){-.....}

and interrupts could create inverse lock ordering between them.

other info that might help us debug this:
 Possible interrupt unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(((&hw->end_timer)));
                               local_irq_disable();
                               lock(&(&priv->lock)->rlock#2);
                               lock(((&hw->end_timer)));
  <Interrupt>
    lock(&(&priv->lock)->rlock#2);

 *** DEADLOCK ***

This is fixed by releasing the main spin lock while performing the
del_timer_sync() call. The timer is prevented from restarting before the
lock is reacquired by a new "stopping" flag which img_ir_handle_data()
checks before updating the timer.

---------------------------------------------------------
swapper/0/0 just changed the state of lock:
 (((&hw->end_timer))){+.-...}, at: [<4006ae5c>] _call_timer_fn+0x0/0xfc
but this lock was taken by another, HARDIRQ-safe lock in the past:
 (&(&priv->lock)->rlock#2){-.....}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this:
 Possible interrupt unsafe locking scenario:
       CPU0                    CPU1
       ----                    ----
  lock(((&hw->end_timer)));
                               local_irq_disable();
                               lock(&(&priv->lock)->rlock#2);
                               lock(((&hw->end_timer)));
  <Interrupt>
    lock(&(&priv->lock)->rlock#2);
 *** DEADLOCK ***
This is fixed by releasing the main spin lock while performing the
del_timer_sync() call. The timer is prevented from restarting before the
lock is reacquired by a new "stopping" flag which img_ir_handle_data()
checks before updating the timer.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Sifan Naeem <sifan.naeem@imgtec.com>
Cc: <stable@vger.kernel.org> # v3.15+
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-12-04 15:39:32 -02:00
..
img-ir [media] img-ir/hw: Fix potential deadlock stopping timer 2014-12-04 15:39:32 -02:00
keymaps media updates for v3.18-rc1 2014-10-10 22:04:49 -04:00
ati_remote.c [media] ati_remote: Use non-alomic __set_bit 2014-07-25 23:52:15 -03:00
ene_ir.c [media] ene_ir: use true/false for boolean vars 2014-09-03 17:59:20 -03:00
ene_ir.h [media] ene_ir: don't use pr_debug after all 2013-07-29 11:49:45 -03:00
fintek-cir.c [media] fintek-cir: just return 0 instead of using a var 2014-09-03 17:59:54 -03:00
fintek-cir.h [media] rc: Fir warnings on m68k arch 2013-11-08 09:45:37 -02:00
gpio-ir-recv.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
igorplugusb.c [media] rc: port IgorPlug-USB to rc-core 2014-11-03 12:18:25 -02:00
iguanair.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
imon.c [media] imon: fix other RC type protocol support 2014-11-03 10:56:51 -02:00
ir-hix5hd2.c [media] ir-hix5hd2 fix build warning 2014-11-03 10:47:05 -02:00
ir-jvc-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-lirc-codec.c [media] media/rc: Send sync space information on the lirc device 2014-11-04 20:41:42 -02:00
ir-mce_kbd-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-nec-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-rc5-decoder.c [media] rc5-decoder: BZ#85721: Fix RC5-SZ decoding 2014-10-30 09:09:28 -02:00
ir-rc6-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-rx51.c [media] ir-rx51: remove deprecated IRQF_DISABLED 2013-10-17 06:09:02 -03:00
ir-sanyo-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-sharp-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-sony-decoder.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ir-xmp-decoder.c [media] rc: Add support for decoding XMP protocol 2014-07-26 19:38:04 -03:00
ite-cir.c [media] ite-cir: just return 0 instead of using a var 2014-09-03 17:59:54 -03:00
ite-cir.h [media] ite-cir: 8709 needs to use pnp resource 2 2011-07-01 16:31:38 -03:00
Kconfig [media] media: rc: add driver for Amlogic Meson IR remote receiver 2014-11-26 13:29:01 -02:00
lirc_dev.c [media] rc: Deletion of unnecessary checks before two function calls 2014-11-25 13:30:38 -02:00
Makefile [media] media: rc: add driver for Amlogic Meson IR remote receiver 2014-11-26 13:29:01 -02:00
mceusb.c [media] mceusb: fix usbdev leak 2014-09-23 16:13:38 -03:00
meson-ir.c [media] media: rc: add driver for Amlogic Meson IR remote receiver 2014-11-26 13:29:01 -02:00
nuvoton-cir.c [media] nuvoton-cir: just return 0 instead of using a var 2014-09-03 17:59:55 -03:00
nuvoton-cir.h [media] nuvoton-cir: Don't touch PS/2 interrupts while initializing 2014-02-04 17:47:26 -02:00
rc-core-priv.h [media] rc: Add support for decoding XMP protocol 2014-07-26 19:38:04 -03:00
rc-ir-raw.c [media] rc-core: fix protocol_change regression in ir_raw_event_register 2014-10-30 09:09:28 -02:00
rc-loopback.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
rc-main.c [media] rc: Deletion of unnecessary checks before two function calls 2014-11-25 13:30:38 -02:00
redrat3.c [media] redrat3: ensure dma is setup properly 2014-12-04 15:28:53 -02:00
st_rc.c [media] st_rc: fix address space casting 2014-09-26 06:47:53 -03:00
streamzap.c [media] rc-core: use USB API functions rather than constants 2014-09-22 17:27:01 -03:00
sunxi-cir.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
ttusbir.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00
winbond-cir.c [media] rc-core: remove protocol arrays 2014-07-25 19:10:43 -03:00