Add options to not apply leap seconds in kernel.

Add kernel_leap option for ptp4l and -x option for phc2sys to disable
setting of the STA_INS/STA_DEL bit to slowly correct the one-second
offset by servo.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
master
Miroslav Lichvar 2013-03-07 17:27:33 +01:00 committed by Richard Cochran
parent e21af97091
commit 4e24248a71
9 changed files with 38 additions and 3 deletions

View File

@ -79,6 +79,7 @@ struct clock {
int freq_est_interval; int freq_est_interval;
int utc_timescale; int utc_timescale;
int leap_set; int leap_set;
int kernel_leap;
enum servo_state servo_state; enum servo_state servo_state;
tmv_t master_offset; tmv_t master_offset;
tmv_t path_delay; tmv_t path_delay;
@ -498,7 +499,8 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
clock_leap = leap_second_status(ts, c->leap_set, clock_leap = leap_second_status(ts, c->leap_set,
&leap, &utc_offset); &leap, &utc_offset);
if (c->leap_set != clock_leap) { if (c->leap_set != clock_leap) {
clockadj_set_leap(c->clkid, clock_leap); if (c->kernel_leap)
clockadj_set_leap(c->clkid, clock_leap);
c->leap_set = clock_leap; c->leap_set = clock_leap;
} }
} }
@ -559,6 +561,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,
c->free_running = dds->free_running; c->free_running = dds->free_running;
c->freq_est_interval = dds->freq_est_interval; c->freq_est_interval = dds->freq_est_interval;
c->kernel_leap = dds->kernel_leap;
c->desc = dds->clock_desc; c->desc = dds->clock_desc;
if (c->free_running) { if (c->free_running) {

View File

@ -383,6 +383,11 @@ static enum parser_result parse_global_setting(const char *option,
return BAD_VALUE; return BAD_VALUE;
cfg->dds.stats_interval = val; cfg->dds.stats_interval = val;
} else if (!strcmp(option, "kernel_leap")) {
if (1 != sscanf(value, "%d", &val))
return BAD_VALUE;
cfg->dds.kernel_leap = val;
} else } else
return NOT_PARSED; return NOT_PARSED;

View File

@ -33,6 +33,7 @@ tx_timestamp_retries 100
use_syslog 1 use_syslog 1
verbose 0 verbose 0
summary_interval 0 summary_interval 0
kernel_leap 1
# #
# Servo Options # Servo Options
# #

1
ds.h
View File

@ -52,6 +52,7 @@ struct default_ds {
int free_running; int free_running;
int freq_est_interval; /*log seconds*/ int freq_est_interval; /*log seconds*/
int stats_interval; /*log seconds*/ int stats_interval; /*log seconds*/
int kernel_leap;
struct clock_description clock_desc; struct clock_description clock_desc;
}; };

View File

@ -32,6 +32,7 @@ tx_timestamp_retries 100
use_syslog 1 use_syslog 1
verbose 0 verbose 0
summary_interval 0 summary_interval 0
kernel_leap 1
# #
# Servo options # Servo options
# #

View File

@ -31,6 +31,8 @@ phc2sys \- synchronize two clocks
] [ ] [
.B \-w .B \-w
] [ ] [
.B \-x
] [
.BI \-l " print-level" .BI \-l " print-level"
] [ ] [
.B \-m .B \-m
@ -127,6 +129,13 @@ option is not used, also keep the offset between the slave and master
times updated according to the currentUtcOffset value obtained from ptp4l and times updated according to the currentUtcOffset value obtained from ptp4l and
the direction of the clock synchronization. the direction of the clock synchronization.
.TP .TP
.B \-x
When a leap second is announced, don't apply it in the kernel by stepping the
clock, but let the servo correct the one-second offset slowly by changing the
clock frequency (unless the
.B \-S
option is used).
.TP
.BI \-l " print-level" .BI \-l " print-level"
Set the maximum syslog level of messages which should be printed or sent to Set the maximum syslog level of messages which should be printed or sent to
the system logger. The default is 6 (LOG_INFO). the system logger. The default is 6 (LOG_INFO).

View File

@ -124,6 +124,7 @@ struct clock {
int sync_offset_direction; int sync_offset_direction;
int leap; int leap;
int leap_set; int leap_set;
int kernel_leap;
struct pmc *pmc; struct pmc *pmc;
int pmc_ds_idx; int pmc_ds_idx;
int pmc_ds_requested; int pmc_ds_requested;
@ -500,7 +501,7 @@ static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts)
if (clock->leap_set != clock_leap) { if (clock->leap_set != clock_leap) {
/* Only the system clock can leap. */ /* Only the system clock can leap. */
if (clock->clkid == CLOCK_REALTIME) if (clock->clkid == CLOCK_REALTIME && clock->kernel_leap)
clockadj_set_leap(clock->clkid, clock_leap); clockadj_set_leap(clock->clkid, clock_leap);
clock->leap_set = clock_leap; clock->leap_set = clock_leap;
} }
@ -525,6 +526,7 @@ static void usage(char *progname)
" -O [offset] slave-master time offset (0)\n" " -O [offset] slave-master time offset (0)\n"
" -u [num] number of clock updates in summary stats (0)\n" " -u [num] number of clock updates in summary stats (0)\n"
" -w wait for ptp4l\n" " -w wait for ptp4l\n"
" -x apply leap seconds by servo instead of kernel\n"
" -h prints this message and exits\n" " -h prints this message and exits\n"
" -v prints the software version and exits\n" " -v prints the software version and exits\n"
"\n", "\n",
@ -542,6 +544,7 @@ int main(int argc, char *argv[])
struct clock dst_clock = { struct clock dst_clock = {
.clkid = CLOCK_REALTIME, .clkid = CLOCK_REALTIME,
.servo_state = SERVO_UNLOCKED, .servo_state = SERVO_UNLOCKED,
.kernel_leap = 1,
}; };
configured_pi_kp = KP; configured_pi_kp = KP;
@ -551,7 +554,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/'); progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0]; progname = progname ? 1+progname : argv[0];
while (EOF != (c = getopt(argc, argv, while (EOF != (c = getopt(argc, argv,
"c:d:hs:P:I:S:R:N:O:i:u:wl:mqv"))) { "c:d:hs:P:I:S:R:N:O:i:u:wxl:mqv"))) {
switch (c) { switch (c) {
case 'c': case 'c':
dst_clock.clkid = clock_open(optarg); dst_clock.clkid = clock_open(optarg);
@ -596,6 +599,9 @@ int main(int argc, char *argv[])
case 'w': case 'w':
wait_sync = 1; wait_sync = 1;
break; break;
case 'x':
dst_clock.kernel_leap = 0;
break;
case 'l': case 'l':
print_level = atoi(optarg); print_level = atoi(optarg);
break; break;

View File

@ -340,6 +340,14 @@ empty string.
.B manufacturerIdentity .B manufacturerIdentity
The manufacturer id which should be an OUI owned by the manufacturer. The manufacturer id which should be an OUI owned by the manufacturer.
The default is 00:00:00. The default is 00:00:00.
.TP
.B kernel_leap
When a leap second is announced, let the kernel apply it by stepping the clock
instead of correcting the one-second offset with servo, which would correct the
one-second offset slowly by changing the clock frequency (unless the
.B pi_offset_const
option is set to correct such offset by stepping).
Relevant only with software time stamping. The default is 1 (enabled).
.SH SEE ALSO .SH SEE ALSO
.BR pmc (8), .BR pmc (8),

View File

@ -53,6 +53,7 @@ static struct config cfg_settings = {
.free_running = 0, .free_running = 0,
.freq_est_interval = 1, .freq_est_interval = 1,
.stats_interval = 0, .stats_interval = 0,
.kernel_leap = 1,
.clock_desc = { .clock_desc = {
.productDescription = { .productDescription = {
.max_symbols = 64, .max_symbols = 64,