[patch 51/55] clocksource: Make delta calculation a function
From: Thomas Gleixner
Date: Fri Jul 11 2014 - 09:47:52 EST
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@xxxxxxxxxxxxx>
---
kernel/time/clocksource.c | 12 +++++++-----
kernel/time/timekeeping.c | 27 ++++++++++++++-------------
kernel/time/timekeeping_internal.h | 6 ++++++
3 files changed, 27 insertions(+), 18 deletions(-)
Index: tip/kernel/time/clocksource.c
===================================================================
--- tip.orig/kernel/time/clocksource.c
+++ tip/kernel/time/clocksource.c
@@ -32,6 +32,7 @@
#include <linux/kthread.h>
#include "tick-internal.h"
+#include "timekeeping_internal.h"
void timecounter_init(struct timecounter *tc,
const struct cyclecounter *cc,
@@ -249,7 +250,7 @@ void clocksource_mark_unstable(struct cl
static void clocksource_watchdog(unsigned long data)
{
struct clocksource *cs;
- cycle_t csnow, wdnow;
+ cycle_t csnow, wdnow, delta;
int64_t wd_nsec, cs_nsec;
int next_cpu, reset_pending;
@@ -282,11 +283,12 @@ static void clocksource_watchdog(unsigne
continue;
}
- wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask,
- watchdog->mult, watchdog->shift);
+ delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask);
+ wd_nsec = clocksource_cyc2ns(delta, watchdog->mult,
+ watchdog->shift);
- cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) &
- cs->mask, cs->mult, cs->shift);
+ delta = clocksource_delta(csnow, cs->cs_last, cs->mask);
+ cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift);
cs->cs_last = csnow;
cs->wd_last = wdnow;
Index: tip/kernel/time/timekeeping.c
===================================================================
--- tip.orig/kernel/time/timekeeping.c
+++ tip/kernel/time/timekeeping.c
@@ -197,7 +197,7 @@ static inline u32 arch_gettimeoffset(voi
static inline s64 timekeeping_get_ns(struct timekeeper *tk)
{
- cycle_t cycle_now, cycle_delta;
+ cycle_t cycle_now, delta;
struct clocksource *clock;
s64 nsec;
@@ -206,9 +206,9 @@ static inline s64 timekeeping_get_ns(str
cycle_now = clock->read(clock);
/* 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;
/* If arch requires, add in get_arch_timeoffset() */
@@ -217,7 +217,7 @@ static inline s64 timekeeping_get_ns(str
static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
{
- cycle_t cycle_now, cycle_delta;
+ cycle_t cycle_now, delta;
struct clocksource *clock;
s64 nsec;
@@ -226,10 +226,10 @@ static inline s64 timekeeping_get_ns_raw
cycle_now = clock->read(clock);
/* 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. */
- 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() */
return nsec + arch_gettimeoffset();
@@ -335,16 +335,15 @@ static void timekeeping_update(struct ti
*/
static void timekeeping_forward_now(struct timekeeper *tk)
{
- cycle_t cycle_now, cycle_delta;
+ cycle_t cycle_now, delta;
struct clocksource *clock;
s64 nsec;
clock = tk->clock;
cycle_now = clock->read(clock);
- cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
- tk->cycle_last = clock->cycle_last = cycle_now;
+ delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask);
- tk->xtime_nsec += cycle_delta * tk->mult;
+ tk->xtime_nsec += delta * tk->mult;
/* If arch requires, add in get_arch_timeoffset() */
tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift;
@@ -352,7 +351,7 @@ static void timekeeping_forward_now(stru
/* Updates tk->base_mono as well */
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);
tk->base_raw = ktime_add_ns(tk->base_raw, nsec);
}
@@ -1063,7 +1062,8 @@ static void timekeeping_resume(void)
u32 shift = clock->shift;
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
@@ -1472,7 +1472,8 @@ void update_wall_time(void)
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
offset = real_tk->cycle_interval;
#else
- offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
+ offset = clocksource_delta(clock->read(clock), clock->cycle_last,
+ clock->mask);
#endif
/* Check if there's really nothing to do */
Index: tip/kernel/time/timekeeping_internal.h
===================================================================
--- tip.orig/kernel/time/timekeeping_internal.h
+++ tip/kernel/time/timekeeping_internal.h
@@ -3,6 +3,7 @@
/*
* timekeeping debug functions
*/
+#include <linux/clocksource.h>
#include <linux/time.h>
#ifdef CONFIG_DEBUG_FS
@@ -11,4 +12,9 @@ extern void tk_debug_account_sleep_time(
#define tk_debug_account_sleep_time(x)
#endif
+static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)
+{
+ return (now -last) & mask;
+}
+
#endif /* _TIMEKEEPING_INTERNAL_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/