diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 4 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 18 | ||||
-rw-r--r-- | kernel/time/tick-oneshot.c | 17 |
3 files changed, 29 insertions, 10 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 1a70c18cdffe..cb8a15c19583 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 ? */ -int hrtimer_hres_active(void) +static inline 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 -int hrtimer_hres_active(void) { return 0; } +static inline 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 18b9f5da4ee9..592bf584d1d2 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -30,7 +30,6 @@ #include <linux/module.h> #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */ #include <linux/tick.h> -#include <linux/hrtimer.h> void timecounter_init(struct timecounter *tc, const struct cyclecounter *cc, @@ -511,13 +510,13 @@ 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 + * Check to make sure we don't switch to a non-highres capable + * clocksource if the tick code is in oneshot mode (highres or nohz) */ - if (hrtimer_hres_active() && + if (tick_oneshot_mode_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); + "Cannot switch while in HRT/NOHZ mode\n", ovr->name); ovr = NULL; override_name[0] = 0; } @@ -550,9 +549,12 @@ sysfs_show_available_clocksources(struct sys_device *dev, spin_lock_irq(&clocksource_lock); list_for_each_entry(src, &clocksource_list, list) { - /* Don't show non-HRES clocksource if HRES is enabled */ - if (!hrtimer_hres_active() || - (src->flags & CLOCK_SOURCE_VALID_FOR_HRES)) + /* + * Don't show non-HRES clocksource if the tick code is + * in one shot mode (highres=on or nohz=on) + */ + if (!tick_oneshot_mode_active() || + (src->flags & CLOCK_SOURCE_VALID_FOR_HRES)) count += snprintf(buf + count, max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "%s ", src->name); diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 2e8de678e767..a96c0e2b89cf 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c @@ -128,6 +128,23 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)) return 0; } +/** + * tick_check_oneshot_mode - check whether the system is in oneshot mode + * + * returns 1 when either nohz or highres are enabled. otherwise 0. + */ +int tick_oneshot_mode_active(void) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + ret = __get_cpu_var(tick_cpu_device).mode == TICKDEV_MODE_ONESHOT; + local_irq_restore(flags); + + return ret; +} + #ifdef CONFIG_HIGH_RES_TIMERS /** * tick_init_highres - switch to high resolution mode |