From: Vincent Cheng <vincent.cheng...@renesas.com>

When clock stepping is unable to happen instantaneously the subsequent
timestamps after a clock step does not reflect the step result and
undesired clock freq and step adjustments will occur.

When using ts2phc to synchronize timestamping clock using external
1 PPS, it could take up to 1 second for the timestamps to reflect the
clock step.

step_window, when set, indicates the number of Sync events after a
clock step in which the clock servo will not do any frequency or
step adjustments.

Signed-off-by: Vincent Cheng <vincent.cheng...@renesas.com>
Signed-off-by: Richard Cochran <richardcoch...@gmail.com>
---
 clock.c  | 20 ++++++++++++++++++++
 config.c |  1 +
 ptp4l.8  |  8 ++++++++
 3 files changed, 29 insertions(+)

diff --git a/clock.c b/clock.c
index e6be5fd..c1fcff6 100644
--- a/clock.c
+++ b/clock.c
@@ -134,6 +134,8 @@ struct clock {
        struct interface *uds_ro_if;
        LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
        struct monitor *slave_event_monitor;
+       int step_window_counter;
+       int step_window;
 };
 
 struct clock the_clock;
@@ -1097,6 +1099,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
        c->kernel_leap = config_get_int(config, NULL, "kernel_leap");
        c->utc_offset = config_get_int(config, NULL, "utc_offset");
        c->time_source = config_get_int(config, NULL, "timeSource");
+       c->step_window = config_get_int(config, NULL, "step_window");
 
        if (c->free_running) {
                c->clkid = CLOCK_INVALID;
@@ -1748,6 +1751,14 @@ int clock_switch_phc(struct clock *c, int phc_index)
        return 0;
 }
 
+static void clock_step_window(struct clock *c)
+{
+       if (!c->step_window) {
+               return;
+       }
+       c->step_window_counter = c->step_window;
+}
+
 static void clock_synchronize_locked(struct clock *c, double adj)
 {
        clockadj_set_freq(c->clkid, -adj);
@@ -1765,6 +1776,14 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
        double adj, weight;
        int64_t offset;
 
+       if (c->step_window_counter) {
+               c->step_window_counter--;
+               pr_debug("skip sync after jump %d/%d",
+                        c->step_window - c->step_window_counter,
+                        c->step_window);
+               return c->servo_state;
+       }
+
        c->ingress_ts = ingress;
 
        tsproc_down_ts(c->tsproc, origin, ingress);
@@ -1809,6 +1828,7 @@ enum servo_state clock_synchronize(struct clock *c, tmv_t 
ingress, tmv_t origin)
                                        -tmv_to_nanoseconds(c->master_offset));
                }
                tsproc_reset(c->tsproc, 0);
+               clock_step_window(c);
                break;
        case SERVO_LOCKED:
                clock_synchronize_locked(c, adj);
diff --git a/config.c b/config.c
index 341f887..c3deddb 100644
--- a/config.c
+++ b/config.c
@@ -303,6 +303,7 @@ struct config_item config_tab[] = {
        GLOB_ITEM_INT("slaveOnly", 0, 0, 1), /*deprecated*/
        GLOB_ITEM_INT("socket_priority", 0, 0, 15),
        GLOB_ITEM_DBL("step_threshold", 0.0, 0.0, DBL_MAX),
+       GLOB_ITEM_INT("step_window", 0, 0, INT_MAX),
        GLOB_ITEM_INT("summary_interval", 0, INT_MIN, INT_MAX),
        PORT_ITEM_INT("syncReceiptTimeout", 0, 0, UINT8_MAX),
        GLOB_ITEM_INT("tc_spanning_tree", 0, 0, 1),
diff --git a/ptp4l.8 b/ptp4l.8
index 0d19171..b04936a 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -705,6 +705,14 @@ one-second offset slowly by changing the clock frequency 
(unless the
 option is set to correct such offset by stepping).
 Relevant only with software time stamping. The default is 1 (enabled).
 .TP
+.B step_window
+When set, indicates the number of Sync events after a clock step that
+the clock will not do any frequency or step adjustments.
+This is used in situations where clock stepping is unable to happen
+instantaneously so there is a lag before the timestamps can settle
+properly to reflect the clock step.
+The default is 0 (disabled).
+.TP
 .B timeSource
 The time source is a single byte code that gives an idea of the kind
 of local clock in use. The value is purely informational, having no
-- 
2.20.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to