lkml.org 
[lkml]   [2015]   [Jun]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 4/5] ntp: Do leapsecond adjustment in adjtimex read path
Date
Since the leapsecond is applied at tick-time, this
means there is a small window of time at the start
of a leap-second where we cross into the next second
before applying the leap.

This patch modified adjtimex so that the leap-second
is applied on the second edge. Providing more correct
leapsecond behavior.

This does make it so that adjtimex()'s returned time
values can be inconsistent with time values read from
gettimeofday() or clock_gettime(CLOCK_REALTIME,...)
for a brief period of one tick at the leapsecond.
However, those other interfaces do not provide the
TIME_OOP time_state return that adjtimex() provides, which
allows the leapsecond to be properly represented. They
instead only see a time discontinuity, and cannot tell the
first 23:59:59 from the repeated 23:59:59 leap second.

This seems like a reasonable tradeoff given clock_gettime()
/ gettimeofday() cannot properly represent a leapsecond,
and users likely care more about performance, while folks
who are using adjtimex() more likely care about leap-second
correctness.

Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
kernel/time/ntp.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 033743e..fb4d98c 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -740,6 +740,24 @@ int __do_adjtimex(struct timex *txc, struct timespec64 *ts, s32 *time_tai)
if (!(time_status & STA_NANO))
txc->time.tv_usec /= NSEC_PER_USEC;

+ /* Handle leapsec adjustments */
+ if (unlikely(ts->tv_sec >= ntp_next_leap_sec)) {
+ if ((time_state == TIME_INS) && (time_status & STA_INS)) {
+ result = TIME_OOP;
+ txc->tai++;
+ txc->time.tv_sec--;
+ }
+ if ((time_state == TIME_DEL) && (time_status & STA_DEL)) {
+ result = TIME_WAIT;
+ txc->tai--;
+ txc->time.tv_sec++;
+ }
+ if ((time_state == TIME_OOP) &&
+ (ts->tv_sec == ntp_next_leap_sec)) {
+ result = TIME_WAIT;
+ }
+ }
+
return result;
}

--
1.9.1


\
 
 \ /
  Last update: 2015-06-12 01:21    [W:0.103 / U:0.144 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site