Loading include/linux/clocksource.h +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ extern void clocksource_suspend(void); extern void clocksource_resume(void); extern struct clocksource * __init clocksource_default_clock(void); extern void clocksource_mark_unstable(struct clocksource *cs); extern void clocksource_select_force(void); extern u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cycles); Loading kernel/time/clocksource.c +33 −13 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ static int finished_booting; #ifdef CONFIG_CLOCKSOURCE_WATCHDOG static void clocksource_watchdog_work(struct work_struct *work); static void clocksource_select(void); static void clocksource_select(bool force); static LIST_HEAD(watchdog_list); static struct clocksource *watchdog; Loading Loading @@ -560,11 +560,12 @@ static inline void clocksource_update_max_deferment(struct clocksource *cs) #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur) static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur, bool force) { struct clocksource *cs; if (!finished_booting || list_empty(&clocksource_list)) if ((!finished_booting && !force) || list_empty(&clocksource_list)) return NULL; /* Loading @@ -582,13 +583,13 @@ static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur) return NULL; } static void __clocksource_select(bool skipcur) static void __clocksource_select(bool skipcur, bool force) { bool oneshot = tick_oneshot_mode_active(); struct clocksource *best, *cs; /* Find the best suitable clocksource */ best = clocksource_find_best(oneshot, skipcur); best = clocksource_find_best(oneshot, skipcur, force); if (!best) return; Loading Loading @@ -641,22 +642,40 @@ static void __clocksource_select(bool skipcur) * Select the clocksource with the best rating, or the clocksource, * which is selected by userspace override. */ static void clocksource_select(void) static void clocksource_select(bool force) { __clocksource_select(false); return __clocksource_select(false, force); } static void clocksource_select_fallback(void) { __clocksource_select(true); __clocksource_select(true, false); } #else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */ static inline void clocksource_select(void) { } static inline void clocksource_select(bool force) { } static inline void clocksource_select_fallback(void) { } #endif /** * clocksource_select_force - Force re-selection of the best clocksource * among registered clocksources * * clocksource_select() can't select the best clocksource before * calling clocksource_done_booting() and since clocksource_select() * should be called with clocksource_mutex held, provide a new API * can be called from other files to select best clockrouce irrespective * of finished_booting flag. */ void clocksource_select_force(void) { mutex_lock(&clocksource_mutex); clocksource_select(true); mutex_unlock(&clocksource_mutex); } /* * clocksource_done_booting - Called near the end of core bootup * Loading @@ -673,7 +692,7 @@ static int __init clocksource_done_booting(void) * Run the watchdog first to eliminate unstable clock sources */ __clocksource_watchdog_work(); clocksource_select(); clocksource_select(false); mutex_unlock(&clocksource_mutex); return 0; } Loading Loading @@ -764,6 +783,7 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq } EXPORT_SYMBOL_GPL(__clocksource_update_freq_scale); /** * __clocksource_register_scale - Used to install new clocksources * @cs: clocksource to be registered Loading @@ -790,7 +810,7 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) clocksource_enqueue_watchdog(cs); clocksource_watchdog_unlock(&flags); clocksource_select(); clocksource_select(false); clocksource_select_watchdog(false); mutex_unlock(&clocksource_mutex); return 0; Loading Loading @@ -818,7 +838,7 @@ void clocksource_change_rating(struct clocksource *cs, int rating) __clocksource_change_rating(cs, rating); clocksource_watchdog_unlock(&flags); clocksource_select(); clocksource_select(false); clocksource_select_watchdog(false); mutex_unlock(&clocksource_mutex); } Loading Loading @@ -928,7 +948,7 @@ static ssize_t current_clocksource_store(struct device *dev, ret = sysfs_get_uname(buf, override_name, count); if (ret >= 0) clocksource_select(); clocksource_select(false); mutex_unlock(&clocksource_mutex); Loading Loading
include/linux/clocksource.h +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ extern void clocksource_suspend(void); extern void clocksource_resume(void); extern struct clocksource * __init clocksource_default_clock(void); extern void clocksource_mark_unstable(struct clocksource *cs); extern void clocksource_select_force(void); extern u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cycles); Loading
kernel/time/clocksource.c +33 −13 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ static int finished_booting; #ifdef CONFIG_CLOCKSOURCE_WATCHDOG static void clocksource_watchdog_work(struct work_struct *work); static void clocksource_select(void); static void clocksource_select(bool force); static LIST_HEAD(watchdog_list); static struct clocksource *watchdog; Loading Loading @@ -560,11 +560,12 @@ static inline void clocksource_update_max_deferment(struct clocksource *cs) #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur) static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur, bool force) { struct clocksource *cs; if (!finished_booting || list_empty(&clocksource_list)) if ((!finished_booting && !force) || list_empty(&clocksource_list)) return NULL; /* Loading @@ -582,13 +583,13 @@ static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur) return NULL; } static void __clocksource_select(bool skipcur) static void __clocksource_select(bool skipcur, bool force) { bool oneshot = tick_oneshot_mode_active(); struct clocksource *best, *cs; /* Find the best suitable clocksource */ best = clocksource_find_best(oneshot, skipcur); best = clocksource_find_best(oneshot, skipcur, force); if (!best) return; Loading Loading @@ -641,22 +642,40 @@ static void __clocksource_select(bool skipcur) * Select the clocksource with the best rating, or the clocksource, * which is selected by userspace override. */ static void clocksource_select(void) static void clocksource_select(bool force) { __clocksource_select(false); return __clocksource_select(false, force); } static void clocksource_select_fallback(void) { __clocksource_select(true); __clocksource_select(true, false); } #else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */ static inline void clocksource_select(void) { } static inline void clocksource_select(bool force) { } static inline void clocksource_select_fallback(void) { } #endif /** * clocksource_select_force - Force re-selection of the best clocksource * among registered clocksources * * clocksource_select() can't select the best clocksource before * calling clocksource_done_booting() and since clocksource_select() * should be called with clocksource_mutex held, provide a new API * can be called from other files to select best clockrouce irrespective * of finished_booting flag. */ void clocksource_select_force(void) { mutex_lock(&clocksource_mutex); clocksource_select(true); mutex_unlock(&clocksource_mutex); } /* * clocksource_done_booting - Called near the end of core bootup * Loading @@ -673,7 +692,7 @@ static int __init clocksource_done_booting(void) * Run the watchdog first to eliminate unstable clock sources */ __clocksource_watchdog_work(); clocksource_select(); clocksource_select(false); mutex_unlock(&clocksource_mutex); return 0; } Loading Loading @@ -764,6 +783,7 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq } EXPORT_SYMBOL_GPL(__clocksource_update_freq_scale); /** * __clocksource_register_scale - Used to install new clocksources * @cs: clocksource to be registered Loading @@ -790,7 +810,7 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) clocksource_enqueue_watchdog(cs); clocksource_watchdog_unlock(&flags); clocksource_select(); clocksource_select(false); clocksource_select_watchdog(false); mutex_unlock(&clocksource_mutex); return 0; Loading Loading @@ -818,7 +838,7 @@ void clocksource_change_rating(struct clocksource *cs, int rating) __clocksource_change_rating(cs, rating); clocksource_watchdog_unlock(&flags); clocksource_select(); clocksource_select(false); clocksource_select_watchdog(false); mutex_unlock(&clocksource_mutex); } Loading Loading @@ -928,7 +948,7 @@ static ssize_t current_clocksource_store(struct device *dev, ret = sysfs_get_uname(buf, override_name, count); if (ret >= 0) clocksource_select(); clocksource_select(false); mutex_unlock(&clocksource_mutex); Loading