diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 0d2f7c8a33d6aa2983fd610bac1fb7b4ebc44cca..58021b0c396d477713ce42dec49bb3bce4701604 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -305,7 +305,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); - +extern int hrtimer_hres_active(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index cb8a15c1958318c52c116d08e33003ad2ea0cc98..1a70c18cdffe5509efab2d9cd6cee9314789a2b4 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -476,7 +476,7 @@ static inline int hrtimer_is_hres_enabled(void) /* * Is the high resolution mode active ? */ -static inline int hrtimer_hres_active(void) +int hrtimer_hres_active(void) { return __get_cpu_var(hrtimer_bases).hres_active; } @@ -704,7 +704,7 @@ static int hrtimer_switch_to_hres(void) #else -static inline int hrtimer_hres_active(void) { return 0; } +int hrtimer_hres_active(void) { return 0; } static inline int hrtimer_is_hres_enabled(void) { return 0; } static inline int hrtimer_switch_to_hres(void) { return 0; } static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 80189f6f1c5a1f7a326c9490e18f571fc8f49ea7..18b9f5da4ee95a0887993b0ae1155ec6f44da01c 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -30,6 +30,7 @@ #include #include /* for spin_unlock_irq() using preempt_count() m68k */ #include +#include void timecounter_init(struct timecounter *tc, const struct cyclecounter *cc, @@ -509,6 +510,18 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, } } + /* + * Check to make sure we don't switch to a non-HRT usable + * clocksource if HRT is enabled and running + */ + if (hrtimer_hres_active() && + !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) { + printk(KERN_WARNING "%s clocksource is not HRT compatible. " + "Cannot switch while in HRT mode\n", ovr->name); + ovr = NULL; + override_name[0] = 0; + } + /* Reselect, when the override name has changed */ if (ovr != clocksource_override) { clocksource_override = ovr; @@ -537,7 +550,10 @@ sysfs_show_available_clocksources(struct sys_device *dev, spin_lock_irq(&clocksource_lock); list_for_each_entry(src, &clocksource_list, list) { - count += snprintf(buf + count, + /* Don't show non-HRES clocksource if HRES is enabled */ + if (!hrtimer_hres_active() || + (src->flags & CLOCK_SOURCE_VALID_FOR_HRES)) + count += snprintf(buf + count, max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "%s ", src->name); }