rtc: Fix hrtimer deadlock
authorThomas Gleixner <tglx@linutronix.de>
Fri, 22 Jul 2011 09:12:51 +0000 (09:12 +0000)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 26 Jul 2011 21:49:59 +0000 (14:49 -0700)
commit3c8bb90efb6e3105206e4aaa9127395feeda5492
tree9ff9771503c219677671bea7f4b2740661d1c5e9
parent53cc2820acbdbcc768675bfaff321f3a8680a317
rtc: Fix hrtimer deadlock

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().

Cc: stable@kernel.org
Reported-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
drivers/rtc/interface.c