Merge branch 'timers-for-linus-clocksource' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-for-linus-clocksource' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: clocksource: prevent selection of low resolution clocksourse also for nohz=on clocksource: sanity check sysfs clocksource changes
This commit is contained in:
@@ -97,10 +97,12 @@ extern void tick_clock_notify(void);
|
|||||||
extern int tick_check_oneshot_change(int allow_nohz);
|
extern int tick_check_oneshot_change(int allow_nohz);
|
||||||
extern struct tick_sched *tick_get_tick_sched(int cpu);
|
extern struct tick_sched *tick_get_tick_sched(int cpu);
|
||||||
extern void tick_check_idle(int cpu);
|
extern void tick_check_idle(int cpu);
|
||||||
|
extern int tick_oneshot_mode_active(void);
|
||||||
# else
|
# else
|
||||||
static inline void tick_clock_notify(void) { }
|
static inline void tick_clock_notify(void) { }
|
||||||
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
|
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
|
||||||
static inline void tick_check_idle(int cpu) { }
|
static inline void tick_check_idle(int cpu) { }
|
||||||
|
static inline int tick_oneshot_mode_active(void) { return 0; }
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#else /* CONFIG_GENERIC_CLOCKEVENTS */
|
#else /* CONFIG_GENERIC_CLOCKEVENTS */
|
||||||
@@ -109,6 +111,7 @@ static inline void tick_cancel_sched_timer(int cpu) { }
|
|||||||
static inline void tick_clock_notify(void) { }
|
static inline void tick_clock_notify(void) { }
|
||||||
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
|
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
|
||||||
static inline void tick_check_idle(int cpu) { }
|
static inline void tick_check_idle(int cpu) { }
|
||||||
|
static inline int tick_oneshot_mode_active(void) { return 0; }
|
||||||
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
|
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
|
||||||
|
|
||||||
# ifdef CONFIG_NO_HZ
|
# ifdef CONFIG_NO_HZ
|
||||||
|
@@ -509,6 +509,18 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 (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/NOHZ mode\n", ovr->name);
|
||||||
|
ovr = NULL;
|
||||||
|
override_name[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reselect, when the override name has changed */
|
/* Reselect, when the override name has changed */
|
||||||
if (ovr != clocksource_override) {
|
if (ovr != clocksource_override) {
|
||||||
clocksource_override = ovr;
|
clocksource_override = ovr;
|
||||||
@@ -537,7 +549,13 @@ sysfs_show_available_clocksources(struct sys_device *dev,
|
|||||||
|
|
||||||
spin_lock_irq(&clocksource_lock);
|
spin_lock_irq(&clocksource_lock);
|
||||||
list_for_each_entry(src, &clocksource_list, list) {
|
list_for_each_entry(src, &clocksource_list, list) {
|
||||||
count += snprintf(buf + count,
|
/*
|
||||||
|
* 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),
|
max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
|
||||||
"%s ", src->name);
|
"%s ", src->name);
|
||||||
}
|
}
|
||||||
|
@@ -128,6 +128,23 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
|
|||||||
return 0;
|
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
|
#ifdef CONFIG_HIGH_RES_TIMERS
|
||||||
/**
|
/**
|
||||||
* tick_init_highres - switch to high resolution mode
|
* tick_init_highres - switch to high resolution mode
|
||||||
|
Reference in New Issue
Block a user