diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-07-16 17:05:10 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2014-07-23 18:01:51 -0400 |
commit | 3a97837784acbf9fed699fc04d1799b0eb742fdf (patch) | |
tree | 12297634077b24bcc6a01b779205043fc2a2a1f1 /kernel | |
parent | 6438e0ddc870f282f7ad46c050c211063a574687 (diff) |
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>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/time/clocksource.c | 12 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 26 | ||||
-rw-r--r-- | kernel/time/timekeeping_internal.h | 6 |
3 files changed, 27 insertions, 17 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index ba3e502c955a..2e949cc9c9f1 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
33 | 33 | ||
34 | #include "tick-internal.h" | 34 | #include "tick-internal.h" |
35 | #include "timekeeping_internal.h" | ||
35 | 36 | ||
36 | void timecounter_init(struct timecounter *tc, | 37 | void timecounter_init(struct timecounter *tc, |
37 | const struct cyclecounter *cc, | 38 | const struct cyclecounter *cc, |
@@ -249,7 +250,7 @@ void clocksource_mark_unstable(struct clocksource *cs) | |||
249 | static void clocksource_watchdog(unsigned long data) | 250 | static void clocksource_watchdog(unsigned long data) |
250 | { | 251 | { |
251 | struct clocksource *cs; | 252 | struct clocksource *cs; |
252 | cycle_t csnow, wdnow; | 253 | cycle_t csnow, wdnow, delta; |
253 | int64_t wd_nsec, cs_nsec; | 254 | int64_t wd_nsec, cs_nsec; |
254 | int next_cpu, reset_pending; | 255 | int next_cpu, reset_pending; |
255 | 256 | ||
@@ -282,11 +283,12 @@ static void clocksource_watchdog(unsigned long data) | |||
282 | continue; | 283 | continue; |
283 | } | 284 | } |
284 | 285 | ||
285 | wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask, | 286 | delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask); |
286 | watchdog->mult, watchdog->shift); | 287 | wd_nsec = clocksource_cyc2ns(delta, watchdog->mult, |
288 | watchdog->shift); | ||
287 | 289 | ||
288 | cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) & | 290 | delta = clocksource_delta(csnow, cs->cs_last, cs->mask); |
289 | cs->mask, cs->mult, cs->shift); | 291 | cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); |
290 | cs->cs_last = csnow; | 292 | cs->cs_last = csnow; |
291 | cs->wd_last = wdnow; | 293 | cs->wd_last = wdnow; |
292 | 294 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index af8051f4420d..531805013786 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -173,7 +173,7 @@ static inline u32 arch_gettimeoffset(void) { return 0; } | |||
173 | 173 | ||
174 | static inline s64 timekeeping_get_ns(struct timekeeper *tk) | 174 | static inline s64 timekeeping_get_ns(struct timekeeper *tk) |
175 | { | 175 | { |
176 | cycle_t cycle_now, cycle_delta; | 176 | cycle_t cycle_now, delta; |
177 | struct clocksource *clock; | 177 | struct clocksource *clock; |
178 | s64 nsec; | 178 | s64 nsec; |
179 | 179 | ||
@@ -182,9 +182,9 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) | |||
182 | cycle_now = clock->read(clock); | 182 | cycle_now = clock->read(clock); |
183 | 183 | ||
184 | /* calculate the delta since the last update_wall_time: */ | 184 | /* calculate the delta since the last update_wall_time: */ |
185 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | 185 | delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask); |
186 | 186 | ||
187 | nsec = cycle_delta * tk->mult + tk->xtime_nsec; | 187 | nsec = delta * tk->mult + tk->xtime_nsec; |
188 | nsec >>= tk->shift; | 188 | nsec >>= tk->shift; |
189 | 189 | ||
190 | /* If arch requires, add in get_arch_timeoffset() */ | 190 | /* If arch requires, add in get_arch_timeoffset() */ |
@@ -193,7 +193,7 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) | |||
193 | 193 | ||
194 | static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) | 194 | static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) |
195 | { | 195 | { |
196 | cycle_t cycle_now, cycle_delta; | 196 | cycle_t cycle_now, delta; |
197 | struct clocksource *clock; | 197 | struct clocksource *clock; |
198 | s64 nsec; | 198 | s64 nsec; |
199 | 199 | ||
@@ -202,10 +202,10 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) | |||
202 | cycle_now = clock->read(clock); | 202 | cycle_now = clock->read(clock); |
203 | 203 | ||
204 | /* calculate the delta since the last update_wall_time: */ | 204 | /* calculate the delta since the last update_wall_time: */ |
205 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | 205 | delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask); |
206 | 206 | ||
207 | /* convert delta to nanoseconds. */ | 207 | /* convert delta to nanoseconds. */ |
208 | nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); | 208 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); |
209 | 209 | ||
210 | /* If arch requires, add in get_arch_timeoffset() */ | 210 | /* If arch requires, add in get_arch_timeoffset() */ |
211 | return nsec + arch_gettimeoffset(); | 211 | return nsec + arch_gettimeoffset(); |
@@ -336,23 +336,23 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) | |||
336 | */ | 336 | */ |
337 | static void timekeeping_forward_now(struct timekeeper *tk) | 337 | static void timekeeping_forward_now(struct timekeeper *tk) |
338 | { | 338 | { |
339 | cycle_t cycle_now, cycle_delta; | 339 | cycle_t cycle_now, delta; |
340 | struct clocksource *clock; | 340 | struct clocksource *clock; |
341 | s64 nsec; | 341 | s64 nsec; |
342 | 342 | ||
343 | clock = tk->clock; | 343 | clock = tk->clock; |
344 | cycle_now = clock->read(clock); | 344 | cycle_now = clock->read(clock); |
345 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | 345 | delta = clocksource_delta(cycle_now, clock->cycle_last, clock->mask); |
346 | tk->cycle_last = clock->cycle_last = cycle_now; | 346 | tk->cycle_last = clock->cycle_last = cycle_now; |
347 | 347 | ||
348 | tk->xtime_nsec += cycle_delta * tk->mult; | 348 | tk->xtime_nsec += delta * tk->mult; |
349 | 349 | ||
350 | /* If arch requires, add in get_arch_timeoffset() */ | 350 | /* If arch requires, add in get_arch_timeoffset() */ |
351 | tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift; | 351 | tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift; |
352 | 352 | ||
353 | tk_normalize_xtime(tk); | 353 | tk_normalize_xtime(tk); |
354 | 354 | ||
355 | nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); | 355 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); |
356 | timespec64_add_ns(&tk->raw_time, nsec); | 356 | timespec64_add_ns(&tk->raw_time, nsec); |
357 | } | 357 | } |
358 | 358 | ||
@@ -1026,7 +1026,8 @@ static void timekeeping_resume(void) | |||
1026 | u32 shift = clock->shift; | 1026 | u32 shift = clock->shift; |
1027 | s64 nsec = 0; | 1027 | s64 nsec = 0; |
1028 | 1028 | ||
1029 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | 1029 | cycle_delta = clocksource_delta(cycle_now, clock->cycle_last, |
1030 | clock->mask); | ||
1030 | 1031 | ||
1031 | /* | 1032 | /* |
1032 | * "cycle_delta * mutl" may cause 64 bits overflow, if the | 1033 | * "cycle_delta * mutl" may cause 64 bits overflow, if the |
@@ -1432,7 +1433,8 @@ void update_wall_time(void) | |||
1432 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET | 1433 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET |
1433 | offset = real_tk->cycle_interval; | 1434 | offset = real_tk->cycle_interval; |
1434 | #else | 1435 | #else |
1435 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | 1436 | offset = clocksource_delta(clock->read(clock), clock->cycle_last, |
1437 | clock->mask); | ||
1436 | #endif | 1438 | #endif |
1437 | 1439 | ||
1438 | /* Check if there's really nothing to do */ | 1440 | /* Check if there's really nothing to do */ |
diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h index e3d28ad236f9..05dfa6b25dc4 100644 --- a/kernel/time/timekeeping_internal.h +++ b/kernel/time/timekeeping_internal.h | |||
@@ -3,6 +3,7 @@ | |||
3 | /* | 3 | /* |
4 | * timekeeping debug functions | 4 | * timekeeping debug functions |
5 | */ | 5 | */ |
6 | #include <linux/clocksource.h> | ||
6 | #include <linux/time.h> | 7 | #include <linux/time.h> |
7 | 8 | ||
8 | #ifdef CONFIG_DEBUG_FS | 9 | #ifdef CONFIG_DEBUG_FS |
@@ -11,4 +12,9 @@ extern void tk_debug_account_sleep_time(struct timespec64 *t); | |||
11 | #define tk_debug_account_sleep_time(x) | 12 | #define tk_debug_account_sleep_time(x) |
12 | #endif | 13 | #endif |
13 | 14 | ||
15 | static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask) | ||
16 | { | ||
17 | return (now - last) & mask; | ||
18 | } | ||
19 | |||
14 | #endif /* _TIMEKEEPING_INTERNAL_H */ | 20 | #endif /* _TIMEKEEPING_INTERNAL_H */ |