diff options
-rw-r--r-- | include/linux/hrtimer.h | 2 | ||||
-rw-r--r-- | include/linux/tick.h | 3 | ||||
-rw-r--r-- | kernel/hrtimer.c | 4 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 18 | ||||
-rw-r--r-- | kernel/time/tick-oneshot.c | 17 |
5 files changed, 33 insertions, 11 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 58021b0c396d..0d2f7c8a33d6 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) | |||
305 | 305 | ||
306 | extern ktime_t ktime_get(void); | 306 | extern ktime_t ktime_get(void); |
307 | extern ktime_t ktime_get_real(void); | 307 | extern ktime_t ktime_get_real(void); |
308 | extern int hrtimer_hres_active(void); | 308 | |
309 | 309 | ||
310 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); | 310 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
311 | 311 | ||
diff --git a/include/linux/tick.h b/include/linux/tick.h index 469b82d88b3b..0482229c07db 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -97,10 +97,12 @@ extern void tick_clock_notify(void); | |||
97 | extern int tick_check_oneshot_change(int allow_nohz); | 97 | extern int tick_check_oneshot_change(int allow_nohz); |
98 | extern struct tick_sched *tick_get_tick_sched(int cpu); | 98 | extern struct tick_sched *tick_get_tick_sched(int cpu); |
99 | extern void tick_check_idle(int cpu); | 99 | extern void tick_check_idle(int cpu); |
100 | extern int tick_oneshot_mode_active(void); | ||
100 | # else | 101 | # else |
101 | static inline void tick_clock_notify(void) { } | 102 | static inline void tick_clock_notify(void) { } |
102 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } | 103 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } |
103 | static inline void tick_check_idle(int cpu) { } | 104 | static inline void tick_check_idle(int cpu) { } |
105 | static inline int tick_oneshot_mode_active(void) { return 0; } | ||
104 | # endif | 106 | # endif |
105 | 107 | ||
106 | #else /* CONFIG_GENERIC_CLOCKEVENTS */ | 108 | #else /* CONFIG_GENERIC_CLOCKEVENTS */ |
@@ -109,6 +111,7 @@ static inline void tick_cancel_sched_timer(int cpu) { } | |||
109 | static inline void tick_clock_notify(void) { } | 111 | static inline void tick_clock_notify(void) { } |
110 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } | 112 | static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } |
111 | static inline void tick_check_idle(int cpu) { } | 113 | static inline void tick_check_idle(int cpu) { } |
114 | static inline int tick_oneshot_mode_active(void) { return 0; } | ||
112 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ | 115 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ |
113 | 116 | ||
114 | # ifdef CONFIG_NO_HZ | 117 | # ifdef CONFIG_NO_HZ |
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) | |||
476 | /* | 476 | /* |
477 | * Is the high resolution mode active ? | 477 | * Is the high resolution mode active ? |
478 | */ | 478 | */ |
479 | int hrtimer_hres_active(void) | 479 | static inline int hrtimer_hres_active(void) |
480 | { | 480 | { |
481 | return __get_cpu_var(hrtimer_bases).hres_active; | 481 | return __get_cpu_var(hrtimer_bases).hres_active; |
482 | } | 482 | } |
@@ -704,7 +704,7 @@ static int hrtimer_switch_to_hres(void) | |||
704 | 704 | ||
705 | #else | 705 | #else |
706 | 706 | ||
707 | int hrtimer_hres_active(void) { return 0; } | 707 | static inline int hrtimer_hres_active(void) { return 0; } |
708 | static inline int hrtimer_is_hres_enabled(void) { return 0; } | 708 | static inline int hrtimer_is_hres_enabled(void) { return 0; } |
709 | static inline int hrtimer_switch_to_hres(void) { return 0; } | 709 | static inline int hrtimer_switch_to_hres(void) { return 0; } |
710 | static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } | 710 | 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 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */ | 31 | #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */ |
32 | #include <linux/tick.h> | 32 | #include <linux/tick.h> |
33 | #include <linux/hrtimer.h> | ||
34 | 33 | ||
35 | void timecounter_init(struct timecounter *tc, | 34 | void timecounter_init(struct timecounter *tc, |
36 | const struct cyclecounter *cc, | 35 | const struct cyclecounter *cc, |
@@ -511,13 +510,13 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, | |||
511 | } | 510 | } |
512 | 511 | ||
513 | /* | 512 | /* |
514 | * Check to make sure we don't switch to a non-HRT usable | 513 | * Check to make sure we don't switch to a non-highres capable |
515 | * clocksource if HRT is enabled and running | 514 | * clocksource if the tick code is in oneshot mode (highres or nohz) |
516 | */ | 515 | */ |
517 | if (hrtimer_hres_active() && | 516 | if (tick_oneshot_mode_active() && |
518 | !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) { | 517 | !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) { |
519 | printk(KERN_WARNING "%s clocksource is not HRT compatible. " | 518 | printk(KERN_WARNING "%s clocksource is not HRT compatible. " |
520 | "Cannot switch while in HRT mode\n", ovr->name); | 519 | "Cannot switch while in HRT/NOHZ mode\n", ovr->name); |
521 | ovr = NULL; | 520 | ovr = NULL; |
522 | override_name[0] = 0; | 521 | override_name[0] = 0; |
523 | } | 522 | } |
@@ -550,9 +549,12 @@ sysfs_show_available_clocksources(struct sys_device *dev, | |||
550 | 549 | ||
551 | spin_lock_irq(&clocksource_lock); | 550 | spin_lock_irq(&clocksource_lock); |
552 | list_for_each_entry(src, &clocksource_list, list) { | 551 | list_for_each_entry(src, &clocksource_list, list) { |
553 | /* Don't show non-HRES clocksource if HRES is enabled */ | 552 | /* |
554 | if (!hrtimer_hres_active() || | 553 | * Don't show non-HRES clocksource if the tick code is |
555 | (src->flags & CLOCK_SOURCE_VALID_FOR_HRES)) | 554 | * in one shot mode (highres=on or nohz=on) |
555 | */ | ||
556 | if (!tick_oneshot_mode_active() || | ||
557 | (src->flags & CLOCK_SOURCE_VALID_FOR_HRES)) | ||
556 | count += snprintf(buf + count, | 558 | count += snprintf(buf + count, |
557 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), | 559 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), |
558 | "%s ", src->name); | 560 | "%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 *)) | |||
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | /** | ||
132 | * tick_check_oneshot_mode - check whether the system is in oneshot mode | ||
133 | * | ||
134 | * returns 1 when either nohz or highres are enabled. otherwise 0. | ||
135 | */ | ||
136 | int tick_oneshot_mode_active(void) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | int ret; | ||
140 | |||
141 | local_irq_save(flags); | ||
142 | ret = __get_cpu_var(tick_cpu_device).mode == TICKDEV_MODE_ONESHOT; | ||
143 | local_irq_restore(flags); | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
131 | #ifdef CONFIG_HIGH_RES_TIMERS | 148 | #ifdef CONFIG_HIGH_RES_TIMERS |
132 | /** | 149 | /** |
133 | * tick_init_highres - switch to high resolution mode | 150 | * tick_init_highres - switch to high resolution mode |