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: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
6438e0ddc8
commit
3a97837784
|
@ -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)
|
||||||
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)
|
||||||
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; }
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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)
|
||||||
#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 @@
|
||||||
/*
|
/*
|
||||||
* 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);
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue