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 |