Commit 3a978377 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by John Stultz

clocksource: Make delta calculation a function

We want to move the TSC sanity check into core code to make NMI safe
accessors to clock monotonic[_raw] possible. For this we need to
sanity check the delta calculation. Create a helper function and
convert all sites to use it.

[ Build fix from jstultz ]
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
parent 6438e0dd
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include "tick-internal.h" #include "tick-internal.h"
#include "timekeeping_internal.h"
void timecounter_init(struct timecounter *tc, void timecounter_init(struct timecounter *tc,
const struct cyclecounter *cc, const struct cyclecounter *cc,
...@@ -249,7 +250,7 @@ void clocksource_mark_unstable(struct clocksource *cs) ...@@ -249,7 +250,7 @@ void clocksource_mark_unstable(struct clocksource *cs)
static void clocksource_watchdog(unsigned long data) static void clocksource_watchdog(unsigned long data)
{ {
struct clocksource *cs; struct clocksource *cs;
cycle_t csnow, wdnow; cycle_t csnow, wdnow, delta;
int64_t wd_nsec, cs_nsec; int64_t wd_nsec, cs_nsec;
int next_cpu, reset_pending; int next_cpu, reset_pending;
...@@ -282,11 +283,12 @@ static void clocksource_watchdog(unsigned long data) ...@@ -282,11 +283,12 @@ static void clocksource_watchdog(unsigned long data)
continue; continue;
} }
wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask, delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask);
watchdog->mult, watchdog->shift); wd_nsec = clocksource_cyc2ns(delta, watchdog->mult,
watchdog->shift);
cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) & delta = clocksource_delta(csnow, cs->cs_last, cs->mask);
cs->mask, cs->mult, cs->shift); cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift);
cs->cs_last = csnow; cs->cs_last = csnow;
cs->wd_last = wdnow; cs->wd_last = wdnow;
......
...@@ -173,7 +173,7 @@ static inline u32 arch_gettimeoffset(void) { return 0; } ...@@ -173,7 +173,7 @@ static inline u32 arch_gettimeoffset(void) { return 0; }
static inline s64 timekeeping_get_ns(struct timekeeper *tk) static inline s64 timekeeping_get_ns(struct timekeeper *tk)
{ {
cycle_t cycle_now, cycle_delta; cycle_t cycle_now, delta;
struct clocksource *clock; struct clocksource *clock;
s64 nsec; s64 nsec;
...@@ -182,9 +182,9 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) ...@@ -182,9 +182,9 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk)
cycle_now = clock->read(clock); cycle_now = clock->read(clock);
/* calculate the delta since the last update_wall_time: */ /* calculate the delta since the last update_wall_time: */
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask);
nsec = cycle_delta * tk->mult + tk->xtime_nsec; nsec = delta * tk->mult + tk->xtime_nsec;
nsec >>= tk->shift; nsec >>= tk->shift;
/* If arch requires, add in get_arch_timeoffset() */ /* If arch requires, add in get_arch_timeoffset() */
...@@ -193,7 +193,7 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) ...@@ -193,7 +193,7 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk)
static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
{ {
cycle_t cycle_now, cycle_delta; cycle_t cycle_now, delta;
struct clocksource *clock; struct clocksource *clock;
s64 nsec; s64 nsec;
...@@ -202,10 +202,10 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) ...@@ -202,10 +202,10 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
cycle_now = clock->read(clock); cycle_now = clock->read(clock);
/* calculate the delta since the last update_wall_time: */ /* calculate the delta since the last update_wall_time: */
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask);
/* convert delta to nanoseconds. */ /* convert delta to nanoseconds. */
nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift);
/* If arch requires, add in get_arch_timeoffset() */ /* If arch requires, add in get_arch_timeoffset() */
return nsec + arch_gettimeoffset(); return nsec + arch_gettimeoffset();
...@@ -336,23 +336,23 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) ...@@ -336,23 +336,23 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
*/ */
static void timekeeping_forward_now(struct timekeeper *tk) static void timekeeping_forward_now(struct timekeeper *tk)
{ {
cycle_t cycle_now, cycle_delta; cycle_t cycle_now, delta;
struct clocksource *clock; struct clocksource *clock;
s64 nsec; s64 nsec;
clock = tk->clock; clock = tk->clock;
cycle_now = clock->read(clock); cycle_now = clock->read(clock);
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask);
tk->cycle_last = clock->cycle_last = cycle_now; tk->cycle_last = clock->cycle_last = cycle_now;
tk->xtime_nsec += cycle_delta * tk->mult; tk->xtime_nsec += delta * tk->mult;
/* If arch requires, add in get_arch_timeoffset() */ /* If arch requires, add in get_arch_timeoffset() */
tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift; tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift;
tk_normalize_xtime(tk); tk_normalize_xtime(tk);
nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift);
timespec64_add_ns(&tk->raw_time, nsec); timespec64_add_ns(&tk->raw_time, nsec);
} }
...@@ -1026,7 +1026,8 @@ static void timekeeping_resume(void) ...@@ -1026,7 +1026,8 @@ static void timekeeping_resume(void)
u32 shift = clock->shift; u32 shift = clock->shift;
s64 nsec = 0; s64 nsec = 0;
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; cycle_delta = clocksource_delta(cycle_now, clock->cycle_last,
clock->mask);
/* /*
* "cycle_delta * mutl" may cause 64 bits overflow, if the * "cycle_delta * mutl" may cause 64 bits overflow, if the
...@@ -1432,7 +1433,8 @@ void update_wall_time(void) ...@@ -1432,7 +1433,8 @@ void update_wall_time(void)
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
offset = real_tk->cycle_interval; offset = real_tk->cycle_interval;
#else #else
offset = (clock->read(clock) - clock->cycle_last) & clock->mask; offset = clocksource_delta(clock->read(clock), clock->cycle_last,
clock->mask);
#endif #endif
/* Check if there's really nothing to do */ /* Check if there's really nothing to do */
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
/* /*
* timekeeping debug functions * timekeeping debug functions
*/ */
#include <linux/clocksource.h>
#include <linux/time.h> #include <linux/time.h>
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
...@@ -11,4 +12,9 @@ extern void tk_debug_account_sleep_time(struct timespec64 *t); ...@@ -11,4 +12,9 @@ extern void tk_debug_account_sleep_time(struct timespec64 *t);
#define tk_debug_account_sleep_time(x) #define tk_debug_account_sleep_time(x)
#endif #endif
static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)
{
return (now - last) & mask;
}
#endif /* _TIMEKEEPING_INTERNAL_H */ #endif /* _TIMEKEEPING_INTERNAL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment