kb:time_sync:leap_seconds:leap_second_information:leap_second_handling_by_the_linux_kernel

Leap Second Handling by the Linux Kernel

There is a test program kernel-time-state available that can be used report the Linux kernel's time state four times per second to monitor how the Linux kernel handles a leap second.

A Meinberg GPS PCI card was prepared to provide a leap second warning at the end of 2016-12-31, when the last recent leap second really occurred.

ntpd 4.2.8p12 was used to provide a Linux kernel 4.20.7 with the time and date as well as the leap second warning flag from the PCI card.

In the output below

  • The first column shows the return code from the adjtimex() function. Possible values are:
    • 0: TIME_OK, synchronized, no leap second warning
    • 1: TIME_INS, synchronized, leap second insertion warning
    • 2: TIME_DEL, synchronized, leap second deletion warning
    • 3: TIME_OOP, leap second in progress
    • 4: TIME_WAIT, leap second has occurred
    • 5: TIME_ERROR, clock not synchronized
  • The 2nd and 3rd columns show the date and time returned by the gmtime() function called with the number of seconds returned by adjtimex(), as well as the fractions part of the returned timestamp.
  • The next values in braces () show the raw timestamp returned from the kernel, where the integer number is what was passed to gmtime(). The appended nanosecond value is a raw indication how long the adjtimex() took to execute.
  • The TAI number is the TAI offset value maintained by the kernel. The initial value is 0 since no leap second file was available to ntpd to set the default value, and after the leap second the value is incremented to 1.
  • The last columns show the status returned by the adjtimex() call, and its interpretation, which should basically comply with the value of the return code.



At the beginning of the record both the return code 1 and the status bits STA_PLL, STA_INS, and STA_NANO indicate that the kernel clock is synchronized, and a positive leap second has been announced.

Since there are 4 calls per second there should be exactly 4 entries with the same second number, but different / increasing fractions within the second. In the output below, all blocks of 4 lines for the same second have been separated by a blank line.

You can clearly see the the marked lines which include the 4 timestamps taken during the leap second have the same raw second count as the previous second, and hence the second number computed by the gmtime() routine is also the same as for the second before, namely 59. There is no second at all labelled 60.

The API calls during the leap second return 3, as expected, and the TAI offset number is already incremented to 1 during the leap second.

After the leap second the adjtimex() call returns 4 to indicate that a leap second has been inserted. The status has still the STA_INS flag set. This has to be cleared by the time synchronization software, ntpd in this case.

Shortly after the next time ntpd has updated the kernel status, and has cleared the STA_INS flag, adjtimex() starts returning 0 to indicate that the kernel clock is synchronized, and leap second processing has finished.

1 2016-12-31 23:59:57.133534631 (1483228797.133534631, 5468 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:57.383743056 (1483228797.383743056, 5235 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:57.633919035 (1483228797.633919035, 5593 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:57.884156728 (1483228797.884156728, 5426 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO

1 2016-12-31 23:59:58.134380523 (1483228798.134380523, 6073 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:58.384616402 (1483228798.384616402, 5904 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:58.634843847 (1483228798.634843847, 5486 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:58.885065643 (1483228798.885065643, 6090 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO

1 2016-12-31 23:59:59.135294673 (1483228799.135294673, 5415 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:59.385513365 (1483228799.385513365, 5956 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:59.635737193 (1483228799.635737193, 5757 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO
1 2016-12-31 23:59:59.885966743 (1483228799.885966743, 6158 ns), TAI 0, status 0x2011: STA_PLL STA_INS STA_NANO

3 2016-12-31 23:59:59.136191002 (1483228799.136191002, 6256 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
3 2016-12-31 23:59:59.386412041 (1483228799.386412041, 6079 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
3 2016-12-31 23:59:59.636688635 (1483228799.636688635, 5739 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
3 2016-12-31 23:59:59.886899568 (1483228799.886899568, 5785 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO

4 2017-01-01 00:00:00.137120139 (1483228800.137120139, 5979 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:00.387327398 (1483228800.387327398, 6376 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:00.637553861 (1483228800.637553861, 5688 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:00.887769450 (1483228800.887769450, 5530 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO

4 2017-01-01 00:00:01.138007012 (1483228801.138007012, 5575 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:01.388231279 (1483228801.388231279, 6601 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:01.638453263 (1483228801.638453263, 5411 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:01.888673665 (1483228801.888673665, 5929 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO

4 2017-01-01 00:00:02.138909451 (1483228802.138909451, 6548 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:02.389128963 (1483228802.389128963, 5410 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:02.639371969 (1483228802.639371969, 5845 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:02.889598787 (1483228802.889598787, 6011 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO

4 2017-01-01 00:00:03.139864270 (1483228803.139864270, 5561 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:03.390101139 (1483228803.390101139, 5894 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:03.640335671 (1483228803.640335671, 5530 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO
4 2017-01-01 00:00:03.890595003 (1483228803.890595003, 6816 ns), TAI 1, status 0x2011: STA_PLL STA_INS STA_NANO

4 2017-01-01 00:00:04.140819889 (1483228804.140819889, 5310 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
4 2017-01-01 00:00:04.391050023 (1483228804.391050023, 5466 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
4 2017-01-01 00:00:04.641279266 (1483228804.641279266, 5806 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
4 2017-01-01 00:00:04.891504529 (1483228804.891504529, 5752 ns), TAI 1, status 0x2001: STA_PLL STA_NANO

0 2017-01-01 00:00:05.141727881 (1483228805.141727881, 6261 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:05.391958794 (1483228805.391958794, 5819 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:05.642184515 (1483228805.642184515, 5392 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:05.892407176 (1483228805.892407176, 6239 ns), TAI 1, status 0x2001: STA_PLL STA_NANO

0 2017-01-01 00:00:06.142636638 (1483228806.142636638, 5470 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:06.392854253 (1483228806.392854253, 5829 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:06.643077079 (1483228806.643077079, 5408 ns), TAI 1, status 0x2001: STA_PLL STA_NANO
0 2017-01-01 00:00:06.893367298 (1483228806.893367298, 6262 ns), TAI 1, status 0x2001: STA_PLL STA_NANO

Martin Burnicki martin.burnicki@meinberg.de 2019-06-06

  • kb/time_sync/leap_seconds/leap_second_information/leap_second_handling_by_the_linux_kernel.txt
  • Last modified: 2020-09-21 12:45
  • by 127.0.0.1