The ktime_t based interfaces are used a lot in performance critical code pathes. Add ktime_t based data so the interfaces don't have to convert from the xtime/timespec based data. Signed-off-by: Thomas Gleixner --- include/linux/timekeeper_internal.h | 3 +++ kernel/time/timekeeping.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) Index: tip/include/linux/timekeeper_internal.h =================================================================== --- tip.orig/include/linux/timekeeper_internal.h +++ tip/include/linux/timekeeper_internal.h @@ -36,6 +36,9 @@ struct timekeeper { /* Clock shifted nano seconds */ u64 xtime_nsec; + /* Monotonic base time */ + ktime_t base_mono; + /* Current CLOCK_REALTIME time in seconds */ u64 xtime_sec; /* CLOCK_REALTIME to CLOCK_MONOTONIC offset */ Index: tip/kernel/time/timekeeping.c =================================================================== --- tip.orig/kernel/time/timekeeping.c +++ tip/kernel/time/timekeeping.c @@ -50,12 +50,30 @@ int __read_mostly timekeeping_suspended; /* Flag for if there is a persistent clock on this platform */ bool __read_mostly persistent_clock_exist = false; +/* + * The xtime based monotonic readout is: + * nsec = (xtime_sec + wtm_sec) * 1e9 + wtm_nsec + now(); + * The ktime based monotonic readout is: + * nsec = base_mono + now(); + * ==> base_mono = (xtime_sec + wtm_sec) * 1e9 + wtm_nsec + */ +static inline void tk_update_ktime_base(struct timekeeper *tk) +{ + s64 nsec; + + nsec = (s64)(tk->xtime_sec + tk->wall_to_monotonic.tv_sec); + nsec *= NSEC_PER_SEC; + nsec += tk->wall_to_monotonic.tv_nsec; + tk->base_mono = ns_to_ktime(nsec); +} + static inline void tk_normalize_xtime(struct timekeeper *tk) { while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) { tk->xtime_nsec -= (u64)NSEC_PER_SEC << tk->shift; tk->xtime_sec++; } + tk_update_ktime_base(tk); } static inline struct timespec64 tk_xtime(struct timekeeper *tk) @@ -71,6 +89,7 @@ static void tk_set_xtime(struct timekeep { tk->xtime_sec = ts->tv_sec; tk->xtime_nsec = (u64)ts->tv_nsec << tk->shift; + tk_update_ktime_base(tk); } static void tk_xtime_add(struct timekeeper *tk, const struct timespec64 *ts) @@ -93,6 +112,7 @@ static void tk_set_wall_to_mono(struct t WARN_ON_ONCE(tk->offs_real.tv64 != timespec64_to_ktime(tmp).tv64); tk->wall_to_monotonic = wtm; set_normalized_timespec64(&tmp, -wtm.tv_sec, -wtm.tv_nsec); + tk_update_ktime_base(tk); tk->offs_real = timespec64_to_ktime(tmp); tk->offs_tai = ktime_add(tk->offs_real, ktime_set(tk->tai_offset, 0)); } @@ -329,6 +349,7 @@ static void timekeeping_forward_now(stru /* If arch requires, add in get_arch_timeoffset() */ tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift; + /* Updates tk->base_mono as well */ tk_normalize_xtime(tk); nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); @@ -1448,6 +1469,10 @@ void update_wall_time(void) * xtime_nsec isn't larger than NSEC_PER_SEC */ clock_set |= accumulate_nsecs_to_secs(tk); + /* + * Update the monotonic base + */ + tk_update_ktime_base(tk); write_seqcount_begin(&tk_core.seq); /* Update clock->cycle_last with the new value */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/