Skip to content

Commit

Permalink
time: Introduce timekeeping_inject_offset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
John Stultz authored and Thomas Gleixner committed Feb 2, 2011
1 parent 0061748 commit c528f7c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/linux/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
extern int timekeeping_valid_for_hres(void);
extern u64 timekeeping_max_deferment(void);
extern void timekeeping_leap_insert(int leapsecond);
extern int timekeeping_inject_offset(struct timespec *ts);

struct tms;
extern void do_sys_times(struct tms *);
Expand Down
36 changes: 36 additions & 0 deletions kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down

0 comments on commit c528f7c

Please sign in to comment.