aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2012-07-17 13:33:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-19 11:58:46 -0400
commit22f4bbcfb131e2392c78ad67af35fdd436d4dd54 (patch)
treefda47805e997a513b7f3c9d86d1e974c5726ca15 /kernel
parent6c89f2ce05ea7e26a7580ad9eb950f2c4f10891b (diff)
timekeeping: Provide hrtimer update function
This is a backport of f6c06abfb3972ad4914cef57d8348fcb2932bc3b To finally fix the infamous leap second issue and other race windows caused by functions which change the offsets between the various time bases (CLOCK_MONOTONIC, CLOCK_REALTIME and CLOCK_BOOTTIME) we need a function which atomically gets the current monotonic time and updates the offsets of CLOCK_REALTIME and CLOCK_BOOTTIME with minimalistic overhead. The previous patch which provides ktime_t offsets allows us to make this function almost as cheap as ktime_get() which is going to be replaced in hrtimer_interrupt(). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ingo Molnar <mingo@kernel.org> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: John Stultz <johnstul@us.ibm.com> Link: http://lkml.kernel.org/r/1341960205-56738-7-git-send-email-johnstul@us.ibm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timekeeping.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index d6477733fc0..f0c7565db31 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1126,6 +1126,40 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
1126 } while (read_seqretry(&xtime_lock, seq)); 1126 } while (read_seqretry(&xtime_lock, seq));
1127} 1127}
1128 1128
1129#ifdef CONFIG_HIGH_RES_TIMERS
1130/**
1131 * ktime_get_update_offsets - hrtimer helper
1132 * @real: pointer to storage for monotonic -> realtime offset
1133 * @_boot: pointer to storage for monotonic -> boottime offset
1134 *
1135 * Returns current monotonic time and updates the offsets
1136 * Called from hrtimer_interupt() or retrigger_next_event()
1137 */
1138ktime_t ktime_get_update_offsets(ktime_t *real, ktime_t *boot)
1139{
1140 ktime_t now;
1141 unsigned int seq;
1142 u64 secs, nsecs;
1143
1144 do {
1145 seq = read_seqbegin(&xtime_lock);
1146
1147 secs = xtime.tv_sec;
1148 nsecs = xtime.tv_nsec;
1149 nsecs += timekeeping_get_ns();
1150 /* If arch requires, add in gettimeoffset() */
1151 nsecs += arch_gettimeoffset();
1152
1153 *real = offs_real;
1154 *boot = offs_boot;
1155 } while (read_seqretry(&xtime_lock, seq));
1156
1157 now = ktime_add_ns(ktime_set(secs, 0), nsecs);
1158 now = ktime_sub(now, *real);
1159 return now;
1160}
1161#endif
1162
1129/** 1163/**
1130 * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format 1164 * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format
1131 */ 1165 */