Index: linux-3.12.5-rt7/include/linux/hrtimer.h =================================================================== --- linux-3.12.5-rt7.orig/include/linux/hrtimer.h 2013-12-27 19:26:13.458162326 +0100 +++ linux-3.12.5-rt7/include/linux/hrtimer.h 2013-12-27 19:30:58.801020576 +0100 @@ -461,8 +461,9 @@ unsigned long delta, const enum hrtimer_mode mode, int clock); extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); -/* Called from the periodic timer tick */ +/* Soft interrupt function to run the hrtimer queues: */ extern void hrtimer_run_queues(void); +extern void hrtimer_run_pending(void); /* Bootup initialization: */ extern void __init hrtimers_init(void); Index: linux-3.12.5-rt7/kernel/hrtimer.c =================================================================== --- linux-3.12.5-rt7.orig/kernel/hrtimer.c 2013-12-27 19:26:13.470160993 +0100 +++ linux-3.12.5-rt7/kernel/hrtimer.c 2013-12-27 19:30:58.802020464 +0100 @@ -1694,6 +1694,30 @@ } /* + * Called from timer softirq every jiffy, expire hrtimers: + * + * For HRT its the fall back code to run the softirq in the timer + * softirq context in case the hrtimer initialization failed or has + * not been done yet. + */ +void hrtimer_run_pending(void) +{ + if (hrtimer_hres_active()) + return; + + /* + * This _is_ ugly: We have to check in the softirq context, + * whether we can switch to highres and / or nohz mode. The + * clocksource switch happens in the timer interrupt with + * xtime_lock held. Notification from there only sets the + * check bit in the tick_oneshot code, otherwise we might + * deadlock vs. xtime_lock. + */ + if (tick_check_oneshot_change(!hrtimer_is_hres_enabled())) + hrtimer_switch_to_hres(); +} + +/* * Called from hardirq context every jiffy */ void hrtimer_run_queues(void) @@ -1706,13 +1730,6 @@ if (hrtimer_hres_active()) return; - /* - * Check whether we can switch to highres mode. - */ - if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()) - && hrtimer_switch_to_hres()) - return; - for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) { base = &cpu_base->clock_base[index]; if (!timerqueue_getnext(&base->active)) Index: linux-3.12.5-rt7/kernel/timer.c =================================================================== --- linux-3.12.5-rt7.orig/kernel/timer.c 2013-12-27 19:26:13.484159439 +0100 +++ linux-3.12.5-rt7/kernel/timer.c 2013-12-27 19:30:58.803020352 +0100 @@ -1443,6 +1443,8 @@ irq_work_run(); #endif + hrtimer_run_pending(); + if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); } @@ -1452,27 +1454,8 @@ */ void run_local_timers(void) { - struct tvec_base *base = __this_cpu_read(tvec_bases); - hrtimer_run_queues(); - /* - * We can access this lockless as we are in the timer - * interrupt. If there are no timers queued, nothing to do in - * the timer softirq. - */ - if (!spin_do_trylock(&base->lock)) { - raise_softirq(TIMER_SOFTIRQ); - return; - } - if (!base->active_timers) - goto out; - - /* Check whether the next pending timer has expired */ - if (time_before_eq(base->next_timer, jiffies)) - raise_softirq(TIMER_SOFTIRQ); -out: - rt_spin_unlock_after_trylock_in_irq(&base->lock); - + raise_softirq(TIMER_SOFTIRQ); } #ifdef __ARCH_WANT_SYS_ALARM