aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/hrtimer.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index e379ef0e9c20..dea4c9124ac8 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -590,7 +590,6 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
590 list_add_tail(&timer->cb_entry, 590 list_add_tail(&timer->cb_entry,
591 &base->cpu_base->cb_pending); 591 &base->cpu_base->cb_pending);
592 timer->state = HRTIMER_STATE_PENDING; 592 timer->state = HRTIMER_STATE_PENDING;
593 raise_softirq(HRTIMER_SOFTIRQ);
594 return 1; 593 return 1;
595 default: 594 default:
596 BUG(); 595 BUG();
@@ -633,6 +632,11 @@ static int hrtimer_switch_to_hres(void)
633 return 1; 632 return 1;
634} 633}
635 634
635static inline void hrtimer_raise_softirq(void)
636{
637 raise_softirq(HRTIMER_SOFTIRQ);
638}
639
636#else 640#else
637 641
638static inline int hrtimer_hres_active(void) { return 0; } 642static inline int hrtimer_hres_active(void) { return 0; }
@@ -651,6 +655,7 @@ static inline int hrtimer_reprogram(struct hrtimer *timer,
651{ 655{
652 return 0; 656 return 0;
653} 657}
658static inline void hrtimer_raise_softirq(void) { }
654 659
655#endif /* CONFIG_HIGH_RES_TIMERS */ 660#endif /* CONFIG_HIGH_RES_TIMERS */
656 661
@@ -850,7 +855,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
850{ 855{
851 struct hrtimer_clock_base *base, *new_base; 856 struct hrtimer_clock_base *base, *new_base;
852 unsigned long flags; 857 unsigned long flags;
853 int ret; 858 int ret, raise;
854 859
855 base = lock_hrtimer_base(timer, &flags); 860 base = lock_hrtimer_base(timer, &flags);
856 861
@@ -884,8 +889,18 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
884 enqueue_hrtimer(timer, new_base, 889 enqueue_hrtimer(timer, new_base,
885 new_base->cpu_base == &__get_cpu_var(hrtimer_bases)); 890 new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
886 891
892 /*
893 * The timer may be expired and moved to the cb_pending
894 * list. We can not raise the softirq with base lock held due
895 * to a possible deadlock with runqueue lock.
896 */
897 raise = timer->state == HRTIMER_STATE_PENDING;
898
887 unlock_hrtimer_base(timer, &flags); 899 unlock_hrtimer_base(timer, &flags);
888 900
901 if (raise)
902 hrtimer_raise_softirq();
903
889 return ret; 904 return ret;
890} 905}
891EXPORT_SYMBOL_GPL(hrtimer_start); 906EXPORT_SYMBOL_GPL(hrtimer_start);