On Wed, Sep 15, 2021 at 12:08:03PM +0200, Miroslav Lichvar wrote:
> When operating as a grandmaster, clear the programmed leap second and
> update the UTC offset when the first announce message after the leap
> second is sent. This guarantees the update happens in +/- 2 announce
> messages around the UTC midnight as required by the specification and
> removes the responsibility from the external process which programmed
> the leap second with the GRANDMASTER_SETTINGS_NP management message.
>
> The code reads the clock directly instead of using a packet timestamp to
> not depend on (timing of) sync messages.
>
> Signed-off-by: Miroslav Lichvar <[email protected]>
> ---
> clock.c | 39 ++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 38 insertions(+), 1 deletion(-)
>
> diff --git a/clock.c b/clock.c
> index c681cbf..c6646c3 100644
> --- a/clock.c
> +++ b/clock.c
> @@ -1892,9 +1892,46 @@ void clock_sync_interval(struct clock *c, int n)
> servo_sync_interval(c->servo, n < 0 ? 1.0 / (1 << -n) : 1 << n);
> }
>
> +static void clock_update_utc_offset(struct clock *c)
> +{
> + struct timespec ts;
> + int leap;
> +
> + if (c->tds.flags & LEAP_61) {
> + leap = 1;
> + } else if (c->tds.flags & LEAP_59) {
> + leap = -1;
> + } else {
> + leap = 0;
> + }
> +
> + /* Don't do anything if not a grandmaster with a leap flag set. */
> + if (c->cur.stepsRemoved > 0 || leap == 0) {
> + return;
> + }
> +
> + clock_gettime(c->clkid, &ts);
> + if (c->time_flags & PTP_TIMESCALE) {
> + ts.tv_sec -= c->utc_offset;
> + }
> +
> + /* Wait until the leap second has passed. */
> + if (leap_second_status(tmv_to_nanoseconds(timespec_to_tmv(ts)),
> + leap, &leap, &c->utc_offset)) {
> + return;
> + }
> +
> + c->time_flags &= ~(LEAP_61 | LEAP_59);
> + clock_update_grandmaster(c);
This is not good. The function, clock_update_grandmaster, implements
the data set update as specified in IEEE 1588 Clause 9.3.5.
> +}
> +
> struct timePropertiesDS clock_time_properties(struct clock *c)
> {
> - struct timePropertiesDS tds = c->tds;
> + struct timePropertiesDS tds;
> +
> + clock_update_utc_offset(c);
The function, clock_time_properties, is a query that should not change
the program state.
With this change, one call chain will be:
port_tx_announce
clock_time_properties
clock_update_utc_offset
clock_update_grandmaster
That clobbers the grandmasterIdentity with the local dds.clockIdentity
in case of BC.
Another bad situation is:
process_delay_req
net_sync_resp_append
clock_time_properties
clock_update_utc_offset
clock_update_grandmaster
Thanks,
Richard
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel