diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-07-16 21:04:10 +0000 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2014-07-23 10:17:57 -0700 |
commit | 7c032df5570388044b4efda3d9f4d2ffb96a3116 (patch) | |
tree | ab8242028af30b3b914b8c33cdfe30fb2feca6c2 | |
parent | f111adfdd7ff7d9fe54b6efa440b80824984749c (diff) |
timekeeping: Provide internal ktime_t based data
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 <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r-- | include/linux/timekeeper_internal.h | 3 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 22 |
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 2cb96235c24..87e0992564f 100644 --- a/include/linux/timekeeper_internal.h +++ b/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 */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index bfe3ea09afc..86a92476c02 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -291,6 +291,26 @@ int pvclock_gtod_unregister_notifier(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(pvclock_gtod_unregister_notifier); +/* + * Update the ktime_t based scalar nsec members of the timekeeper + */ +static inline void tk_update_ktime_data(struct timekeeper *tk) +{ + s64 nsec; + + /* + * 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 + */ + 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); +} + /* must hold timekeeper_lock */ static void timekeeping_update(struct timekeeper *tk, unsigned int action) { @@ -301,6 +321,8 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) update_vsyscall(tk); update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET); + tk_update_ktime_data(tk); + if (action & TK_MIRROR) memcpy(&shadow_timekeeper, &tk_core.timekeeper, sizeof(tk_core.timekeeper)); |