time: Introduce timekeeping_inject_offset

This adds a kernel-internal timekeeping interface to add or subtract
a fixed amount from CLOCK_REALTIME. This makes it so kernel users or
interfaces trying to do so do not have to read the time, then add an
offset and then call settimeofday(), which adds some extra error in
comparision to just simply adding the offset in the kernel timekeeping
core.

Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
LKML-Reference: <20110201134419.584311693@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
John Stultz
2011-02-01 13:52:17 +00:00
committed by Thomas Gleixner
parent 0061748dd2
commit c528f7c6c2
2 changed files with 37 additions and 0 deletions

View File

@@ -387,6 +387,42 @@ int do_settimeofday(const struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
/**
* timekeeping_inject_offset - Adds or subtracts from the current time.
* @tv: pointer to the timespec variable containing the offset
*
* Adds or subtracts an offset value from the current time.
*/
int timekeeping_inject_offset(struct timespec *ts)
{
unsigned long flags;
if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
write_seqlock_irqsave(&xtime_lock, flags);
timekeeping_forward_now();
xtime = timespec_add(xtime, *ts);
wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts);
timekeeper.ntp_error = 0;
ntp_clear();
update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
timekeeper.mult);
write_sequnlock_irqrestore(&xtime_lock, flags);
/* signal hrtimers about time change */
clock_was_set();
return 0;
}
EXPORT_SYMBOL(timekeeping_inject_offset);
/**
* change_clocksource - Swaps clocksources if a new one is available
*