Discussion:
[Linuxptp-devel] [PATCH] phc2sys: add option for maximum correction on start.
Miroslav Lichvar
2012-09-05 15:00:31 UTC
Permalink
On start, wait until the PHC and system clock are closer than the
specified limit. This can be used to avoid setting the system clock to
PHC until it's synchronized, assuming the system clock is already
close to the right time.

Signed-off-by: Miroslav Lichvar <***@redhat.com>
---
phc2sys.c | 27 ++++++++++++++++++++-------
1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/phc2sys.c b/phc2sys.c
index b07701e..a035be8 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -206,6 +206,7 @@ static void usage(char *progname)
" -h prints this message and exits\n"
" -r [val] reading the PHC device takes 'val' nanoseconds\n"
" -s [device] set the time from this PHC device\n"
+ " -m [val] wait until offset is below 'val' seconds\n"
" -P [val] set proportional constant to 'val'\n"
" -I [val] set integration constant to 'val'\n"
" -R [val] set PHC update rate to 'val' Hz\n"
@@ -220,13 +221,13 @@ int main(int argc, char *argv[])
char *device = NULL, *progname;
clockid_t src = CLOCK_INVALID, dst = CLOCK_REALTIME;
uint64_t pps_ts, phc_ts;
- int64_t pps_offset, phc_offset;
+ int64_t pps_offset, phc_offset, max_offset = 0;
int c, fd = 0, rdelay = 0, phc_readings = 5, phc_rate = 1;

/* Process the command line arguments. */
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
- while (EOF != (c = getopt(argc, argv, "c:d:hr:s:P:I:R:N:"))) {
+ while (EOF != (c = getopt(argc, argv, "c:d:hr:s:m:P:I:R:N:"))) {
switch (c) {
case 'c':
dst = clock_open(optarg);
@@ -240,6 +241,9 @@ int main(int argc, char *argv[])
case 's':
src = clock_open(optarg);
break;
+ case 'm':
+ max_offset = atof(optarg) * 1e9;
+ break;
case 'P':
kp = atof(optarg);
break;
@@ -273,11 +277,20 @@ int main(int argc, char *argv[])
}
}
if (src != CLOCK_INVALID) {
- struct timespec now;
- if (clock_gettime(src, &now))
- perror("clock_gettime");
- if (clock_settime(dst, &now))
- perror("clock_settime");
+ while (1) {
+ if (!read_phc(src, dst, rdelay, phc_readings,
+ &phc_offset, &phc_ts))
+ return 1;
+
+ if (max_offset <= 0 || (phc_offset < max_offset &&
+ phc_offset > -max_offset))
+ break;
+
+ /* Try again later. */
+ usleep(1000000);
+ continue;
+ }
+ clock_step(dst, -phc_offset);
}
while (1) {
if (fd > 0) {
--
1.7.7.6
Richard Cochran
2012-09-06 07:03:28 UTC
Permalink
Post by Miroslav Lichvar
On start, wait until the PHC and system clock are closer than the
specified limit. This can be used to avoid setting the system clock to
PHC until it's synchronized, assuming the system clock is already
close to the right time.
Doesn't this mean that, if the SYS is off and PHC is okay, that we
will wait forever?

Isn't it simpler just to set the PHC to SYS at boot time?

Thanks,
Richard
Miroslav Lichvar
2012-09-06 16:25:14 UTC
Permalink
Post by Richard Cochran
Post by Miroslav Lichvar
On start, wait until the PHC and system clock are closer than the
specified limit. This can be used to avoid setting the system clock to
PHC until it's synchronized, assuming the system clock is already
close to the right time.
Doesn't this mean that, if the SYS is off and PHC is okay, that we
will wait forever?
Yes. If we know the system clock wasn't synchronized, this option
shouldn't be used. I think the RTC or ntpdate run on boot should be
good enough.
Post by Richard Cochran
Isn't it simpler just to set the PHC to SYS at boot time?
If the error in the system time is too large, it will take a long time
for phc2sys to correct it later.

This is only a temporary solution to get something that can be
automatically started on boot. I guess the proper solution will need
to include some communication with ptp4l to get the synchronization
status, the epoch in which the PHC is kept and also the UTC-TAI offset.
--
Miroslav Lichvar
Richard Cochran
2012-09-06 18:39:39 UTC
Permalink
Post by Miroslav Lichvar
This is only a temporary solution to get something that can be
automatically started on boot. I guess the proper solution will need
to include some communication with ptp4l to get the synchronization
status, the epoch in which the PHC is kept and also the UTC-TAI offset.
Yes, this is the larger issue to tackle. I think this is a somewhat
thorny problem with a few potential gotchas, but I believe it should
be possible to handle the start up in a reasonable way. I will be
really happy if you would take the lead in coming up with a concept
for the whole set of issues:

rc.init/rtc/ntp/ptp/utc/tai/sysclock/phc

In my experience, people *love* to argue about the whole UTC TAI
thing, so no matter what you propose, someone is sure to complain.

In any case, we should probably somehow get John Stultz (now on CC) in
on this discussion, too.

Thanks,
Richard

PS regarding TAI:

It seems that on my debian PC with ntpd running, the TAI offset in the
NTP kernel code is always zero, even though ntpd should know what the
offset it. It looks like ntpd only sets this kernel variable when the
TAI offset changes (at a leap second) - not too useful :(

Also, I wonder whether a computer should write down the TAI offset
somewhere (with at least a record of the last leap), so that it can
start (still offline) with a correct offset in those cases where a new
leap second cannot have happened while the power was off.
John Stultz
2012-09-06 19:45:10 UTC
Permalink
Post by Richard Cochran
Post by Miroslav Lichvar
This is only a temporary solution to get something that can be
automatically started on boot. I guess the proper solution will need
to include some communication with ptp4l to get the synchronization
status, the epoch in which the PHC is kept and also the UTC-TAI offset.
Yes, this is the larger issue to tackle. I think this is a somewhat
thorny problem with a few potential gotchas, but I believe it should
be possible to handle the start up in a reasonable way. I will be
really happy if you would take the lead in coming up with a concept
rc.init/rtc/ntp/ptp/utc/tai/sysclock/phc
In my experience, people *love* to argue about the whole UTC TAI
thing, so no matter what you propose, someone is sure to complain.
In any case, we should probably somehow get John Stultz (now on CC) in
on this discussion, too.
Thanks,
Richard
It seems that on my debian PC with ntpd running, the TAI offset in the
NTP kernel code is always zero, even though ntpd should know what the
offset it. It looks like ntpd only sets this kernel variable when the
TAI offset changes (at a leap second) - not too useful :(
Also, I wonder whether a computer should write down the TAI offset
somewhere (with at least a record of the last leap), so that it can
start (still offline) with a correct offset in those cases where a new
leap second cannot have happened while the power was off.
I ran into this too recently. With NTP 4.2.6+ you can provide a leapfile
that ntpd will use to set the TAI offset.

http://support.ntp.org/bin/view/Support/ConfiguringNTP#Section_6.14.

But this isn't how ntpd is usually configured on most distros.

Also, someone posted in the lwn comments how to generate tai from the
timezone files:
https://lwn.net/Articles/504985/
http://lindi.iki.fi/lindi/tai.c

Which might be a usable way to init TAI at boot time from UTC.

thanks
-john

Loading...