rtc: fix hrtimer deadlock
commite9c5291ba063473a5560d3387773e9a6997bad65
authorThomas Gleixner <tglx@linutronix.de>
Tue, 26 Jul 2011 23:08:20 +0000 (26 16:08 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 5 Aug 2011 04:58:32 +0000 (4 21:58 -0700)
treeb9293ac3cf2da429a302e82fdc84fa08662f4329
parentcc4b6e7755a8c351d7ddf32b5f2e7f101cea5aa6
rtc: fix hrtimer deadlock

commit b830ac1d9a2262093bb0f3f6a2fd2a1c8278daf5 upstream.

Ben reported a lockup related to rtc. The lockup happens due to:

CPU0                                        CPU1

rtc_irq_set_state()     __run_hrtimer()
  spin_lock_irqsave(&rtc->irq_task_lock)    rtc_handle_legacy_irq();
      spin_lock(&rtc->irq_task_lock);
  hrtimer_cancel()
    while (callback_running);

So the running callback never finishes as it's blocked on
rtc->irq_task_lock.

Use hrtimer_try_to_cancel() instead and drop rtc->irq_task_lock while
waiting for the callback.  Fix this for both rtc_irq_set_state() and
rtc_irq_set_freq().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reported-by: Ben Greear <greearb@candelatech.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/rtc/interface.c