Commit b830ac1d9a2262093bb0f3f6a2fd2a1c8278daf5

Authored by Thomas Gleixner
Committed by Linus Torvalds
1 parent 431e2bcc37

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

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>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 37 additions and 19 deletions Side-by-side Diff

drivers/rtc/interface.c
... ... @@ -636,6 +636,29 @@
636 636 }
637 637 EXPORT_SYMBOL_GPL(rtc_irq_unregister);
638 638  
  639 +static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
  640 +{
  641 + /*
  642 + * We unconditionally cancel the timer here, because otherwise
  643 + * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
  644 + * when we manage to start the timer before the callback
  645 + * returns HRTIMER_RESTART.
  646 + *
  647 + * We cannot use hrtimer_cancel() here as a running callback
  648 + * could be blocked on rtc->irq_task_lock and hrtimer_cancel()
  649 + * would spin forever.
  650 + */
  651 + if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0)
  652 + return -1;
  653 +
  654 + if (enabled) {
  655 + ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq);
  656 +
  657 + hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
  658 + }
  659 + return 0;
  660 +}
  661 +
639 662 /**
640 663 * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
641 664 * @rtc: the rtc device
642 665  
643 666  
644 667  
... ... @@ -651,24 +674,21 @@
651 674 int err = 0;
652 675 unsigned long flags;
653 676  
  677 +retry:
654 678 spin_lock_irqsave(&rtc->irq_task_lock, flags);
655 679 if (rtc->irq_task != NULL && task == NULL)
656 680 err = -EBUSY;
657 681 if (rtc->irq_task != task)
658 682 err = -EACCES;
659   - if (err)
660   - goto out;
661   -
662   - if (enabled) {
663   - ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
664   - hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
665   - } else {
666   - hrtimer_cancel(&rtc->pie_timer);
  683 + if (!err) {
  684 + if (rtc_update_hrtimer(rtc, enabled) < 0) {
  685 + spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
  686 + cpu_relax();
  687 + goto retry;
  688 + }
  689 + rtc->pie_enabled = enabled;
667 690 }
668   - rtc->pie_enabled = enabled;
669   -out:
670 691 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
671   -
672 692 return err;
673 693 }
674 694 EXPORT_SYMBOL_GPL(rtc_irq_set_state);
675 695  
676 696  
... ... @@ -690,20 +710,18 @@
690 710  
691 711 if (freq <= 0 || freq > 5000)
692 712 return -EINVAL;
693   -
  713 +retry:
694 714 spin_lock_irqsave(&rtc->irq_task_lock, flags);
695 715 if (rtc->irq_task != NULL && task == NULL)
696 716 err = -EBUSY;
697 717 if (rtc->irq_task != task)
698 718 err = -EACCES;
699   - if (err == 0) {
  719 + if (!err) {
700 720 rtc->irq_freq = freq;
701   - if (rtc->pie_enabled) {
702   - ktime_t period;
703   - hrtimer_cancel(&rtc->pie_timer);
704   - period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
705   - hrtimer_start(&rtc->pie_timer, period,
706   - HRTIMER_MODE_REL);
  721 + if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
  722 + spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
  723 + cpu_relax();
  724 + goto retry;
707 725 }
708 726 }
709 727 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);