View difference between Paste ID: MYLqbmZw and mhhh0WJU
SHOW: | | - or go back to the newest paste.
1
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
2
index bdbf77db..79a7a35 100644
3
--- a/include/linux/hrtimer.h
4
+++ b/include/linux/hrtimer.h
5
@@ -461,8 +461,9 @@ extern int schedule_hrtimeout_range_clock(ktime_t *expires,
6
 		unsigned long delta, const enum hrtimer_mode mode, int clock);
7
 extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
8
 
9
-/* Called from the periodic timer tick */
10
+/* Soft interrupt function to run the hrtimer queues: */
11
 extern void hrtimer_run_queues(void);
12
+extern void hrtimer_run_pending(void);
13
 
14
 /* Bootup initialization: */
15
 extern void __init hrtimers_init(void);
16
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
17
index c19183d..c6d8232 100644
18
--- a/kernel/hrtimer.c
19
+++ b/kernel/hrtimer.c
20
@@ -1694,6 +1694,30 @@ static void run_hrtimer_softirq(struct softirq_action *h)
21
 }
22
 
23
 /*
24
+ * Called from timer softirq every jiffy, expire hrtimers:
25
+ *
26
+ * For HRT its the fall back code to run the softirq in the timer
27
+ * softirq context in case the hrtimer initialization failed or has
28
+ * not been done yet.
29
+ */
30
+void hrtimer_run_pending(void)
31
+{
32
+	if (hrtimer_hres_active())
33
+		return;
34
+
35
+	/*
36
+	 * This _is_ ugly: We have to check in the softirq context,
37
+	 * whether we can switch to highres and / or nohz mode. The
38
+	 * clocksource switch happens in the timer interrupt with
39
+	 * xtime_lock held. Notification from there only sets the
40
+	 * check bit in the tick_oneshot code, otherwise we might
41
+	 * deadlock vs. xtime_lock.
42
+	 */
43
+	if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
44
+		hrtimer_switch_to_hres();
45
+}
46
+
47
+/*
48
  * Called from hardirq context every jiffy
49
  */
50
 void hrtimer_run_queues(void)
51
@@ -1706,13 +1730,6 @@ void hrtimer_run_queues(void)
52
 	if (hrtimer_hres_active())
53
 		return;
54
 
55
-	/*
56
-	 * Check whether we can switch to highres mode.
57
-	 */
58
-	if (tick_check_oneshot_change(!hrtimer_is_hres_enabled())
59
-	    && hrtimer_switch_to_hres())
60
-		return;
61
-
62
 	for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) {
63
 		base = &cpu_base->clock_base[index];
64
 		if (!timerqueue_getnext(&base->active))
65
diff --git a/kernel/timer.c b/kernel/timer.c
66-
index cc34e42..835b608 100644
66+
index cc34e42..7c523a4 100644
67
--- a/kernel/timer.c
68
+++ b/kernel/timer.c
69-
@@ -1400,7 +1400,7 @@ unsigned long get_next_timer_interrupt(unsigned long now)
69+
70-
 		expires = base->next_timer;
70+
71-
 	}
71+
72-
 #ifdef CONFIG_PREEMPT_RT_FULL
72+
73
+	hrtimer_run_pending();
74-
+	rt_spin_unlock(&base->lock);
74+
75-
 #else
75+
76-
 	spin_unlock(&base->lock);
76+
77
 }
78
@@ -1452,39 +1454,8 @@ static void run_timer_softirq(struct softirq_action *h)
79
  */
80
 void run_local_timers(void)
81
 {
82
-	struct tvec_base *base = __this_cpu_read(tvec_bases);
83
-
84
 	hrtimer_run_queues();
85
-	/*
86
-	 * We can access this lockless as we are in the timer
87
-	 * interrupt. If there are no timers queued, nothing to do in
88
-	 * the timer softirq.
89
-	 */
90
-#ifdef CONFIG_PREEMPT_RT_FULL
91
-	/* On RT, irq work runs from softirq */
92
-	if (irq_work_needs_cpu()) {
93
-		raise_softirq(TIMER_SOFTIRQ);
94
-		return;
95
-	}
96
-
97
-	if (!spin_do_trylock(&base->lock)) {
98
-		raise_softirq(TIMER_SOFTIRQ);
99
-		return;
100
-	}
101
-#endif
102
-
103
-	if (!base->active_timers)
104
-		goto out;
105
-
106
-	/* Check whether the next pending timer has expired */
107
-	if (time_before_eq(base->next_timer, jiffies))
108
-		raise_softirq(TIMER_SOFTIRQ);
109
-out:
110
-#ifdef CONFIG_PREEMPT_RT_FULL
111
-	rt_spin_unlock_after_trylock_in_irq(&base->lock);
112
-#endif
113
-	/* The ; ensures that gcc won't complain in the !RT case */
114
-	;
115
+	raise_softirq(TIMER_SOFTIRQ);
116
 }
117
 
118
 #ifdef __ARCH_WANT_SYS_ALARM