|
@@ -540,19 +540,19 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
|
|
|
/*
|
|
|
* Switch to high resolution mode
|
|
|
*/
|
|
|
-static void hrtimer_switch_to_hres(void)
|
|
|
+static int hrtimer_switch_to_hres(void)
|
|
|
{
|
|
|
struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases);
|
|
|
unsigned long flags;
|
|
|
|
|
|
if (base->hres_active)
|
|
|
- return;
|
|
|
+ return 1;
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
|
|
if (tick_init_highres()) {
|
|
|
local_irq_restore(flags);
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
}
|
|
|
base->hres_active = 1;
|
|
|
base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES;
|
|
@@ -565,13 +565,14 @@ static void hrtimer_switch_to_hres(void)
|
|
|
local_irq_restore(flags);
|
|
|
printk(KERN_INFO "Switched to high resolution mode on CPU %d\n",
|
|
|
smp_processor_id());
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
static inline int hrtimer_hres_active(void) { return 0; }
|
|
|
static inline int hrtimer_is_hres_enabled(void) { return 0; }
|
|
|
-static inline void hrtimer_switch_to_hres(void) { }
|
|
|
+static inline int hrtimer_switch_to_hres(void) { return 0; }
|
|
|
static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { }
|
|
|
static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
|
|
|
struct hrtimer_clock_base *base)
|
|
@@ -1130,6 +1131,9 @@ static inline void run_hrtimer_queue(struct hrtimer_cpu_base *cpu_base,
|
|
|
if (base->softirq_time.tv64 <= timer->expires.tv64)
|
|
|
break;
|
|
|
|
|
|
+#ifdef CONFIG_HIGH_RES_TIMERS
|
|
|
+ WARN_ON_ONCE(timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ);
|
|
|
+#endif
|
|
|
timer_stats_account_hrtimer(timer);
|
|
|
|
|
|
fn = timer->function;
|
|
@@ -1173,7 +1177,8 @@ void hrtimer_run_queues(void)
|
|
|
* deadlock vs. xtime_lock.
|
|
|
*/
|
|
|
if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
|
|
|
- hrtimer_switch_to_hres();
|
|
|
+ if (hrtimer_switch_to_hres())
|
|
|
+ return;
|
|
|
|
|
|
hrtimer_get_softirq_time(cpu_base);
|
|
|
|