Skip to content

Commit e3ff9c3

Browse files
committed
timekeeping: Repair ktime_get_coarse*() granularity
Jason reported that the coarse ktime based time getters advance only once per second and not once per tick as advertised. The code reads only the monotonic base time, which advances once per second. The nanoseconds are accumulated on every tick in xtime_nsec up to a second and the regular time getters take this nanoseconds offset into account, but the ktime_get_coarse*() implementation fails to do so. Add the accumulated xtime_nsec value to the monotonic base time to get the proper per tick advancing coarse tinme. Fixes: b9ff604 ("timekeeping: Add ktime_get_coarse_with_offset") Reported-by: Jason A. Donenfeld <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Jason A. Donenfeld <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Clemens Ladisch <[email protected]> Cc: Sultan Alsawaf <[email protected]> Cc: Waiman Long <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 6cb3dd7 commit e3ff9c3

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

kernel/time/timekeeping.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,18 @@ ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs)
808808
struct timekeeper *tk = &tk_core.timekeeper;
809809
unsigned int seq;
810810
ktime_t base, *offset = offsets[offs];
811+
u64 nsecs;
811812

812813
WARN_ON(timekeeping_suspended);
813814

814815
do {
815816
seq = read_seqcount_begin(&tk_core.seq);
816817
base = ktime_add(tk->tkr_mono.base, *offset);
818+
nsecs = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
817819

818820
} while (read_seqcount_retry(&tk_core.seq, seq));
819821

820-
return base;
821-
822+
return base + nsecs;
822823
}
823824
EXPORT_SYMBOL_GPL(ktime_get_coarse_with_offset);
824825

0 commit comments

Comments
 (0)