This patch lets the ports (rather than the clock) remember the clock ID,
passing it back to the clock code during synchronization. This does not
represent a functional change, but rather paves the way for ports to
override the clock ID when running a "jbod" BC.
Signed-off-by: Richard Cochran <***@gmail.com>
---
clock.c | 50 ++++++++++++++++++++++++--------------------------
clock.h | 2 ++
port.c | 8 ++++++--
port.h | 4 +++-
4 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/clock.c b/clock.c
index df82d2b..ca902ef 100644
--- a/clock.c
+++ b/clock.c
@@ -72,7 +72,6 @@ struct clock_subscriber {
};
struct clock {
- clockid_t clkid;
struct servo *servo;
struct defaultDS dds;
struct dataset default_dataset;
@@ -268,9 +267,6 @@ void clock_destroy(struct clock *c)
}
port_close(c->uds_port);
free(c->pollfd);
- if (c->clkid != CLOCK_REALTIME) {
- phc_close(c->clkid);
- }
servo_destroy(c->servo);
filter_destroy(c->delay_filter);
stats_destroy(c->stats.offset);
@@ -654,7 +650,7 @@ static void clock_update_slave(struct clock *c)
}
}
-static int clock_utc_correct(struct clock *c, tmv_t ingress)
+static int clock_utc_correct(struct clock *c, clockid_t clkid, tmv_t ingress)
{
struct timespec offset;
int utc_offset, leap, clock_leap;
@@ -680,7 +676,7 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
}
/* Handle leap seconds. */
- if ((leap || c->leap_set) && c->clkid == CLOCK_REALTIME) {
+ if ((leap || c->leap_set) && clkid == CLOCK_REALTIME) {
/* If the clock will be stepped, the time stamp has to be the
target time. Ignore possible 1 second error in utc_offset. */
if (c->servo_state == SERVO_UNLOCKED) {
@@ -711,7 +707,7 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
/* Update TAI-UTC offset of the system clock if valid and traceable. */
if (c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE &&
- c->utc_offset_set != utc_offset && c->clkid == CLOCK_REALTIME) {
+ c->utc_offset_set != utc_offset && clkid == CLOCK_REALTIME) {
sysclk_set_tai_offset(utc_offset);
c->utc_offset_set = utc_offset;
}
@@ -752,7 +748,7 @@ UInteger8 clock_class(struct clock *c)
return c->dds.clockQuality.clockClass;
}
-static int clock_add_port(struct clock *c, int phc_index,
+static int clock_add_port(struct clock *c, clockid_t clkid, int phc_index,
enum timestamp_type timestamping,
struct interface *iface)
{
@@ -760,7 +756,7 @@ static int clock_add_port(struct clock *c, int phc_index,
if (clock_resize_pollfd(c, c->nports + 1))
return -1;
- p = port_open(phc_index, timestamping, ++c->last_port_number,
+ p = port_open(clkid, phc_index, timestamping, ++c->last_port_number,
iface, c);
if (!p) {
/* No need to shrink pollfd */
@@ -796,6 +792,7 @@ struct clock *clock_create(int phc_index, struct interfaces_head *ifaces,
struct interface *udsif = &c->uds_interface;
struct interface *iface;
struct timespec ts;
+ clockid_t clkid;
clock_gettime(CLOCK_REALTIME, &ts);
srandom(ts.tv_sec ^ ts.tv_nsec);
@@ -816,27 +813,27 @@ struct clock *clock_create(int phc_index, struct interfaces_head *ifaces,
c->desc = dds->clock_desc;
if (c->free_running) {
- c->clkid = CLOCK_INVALID;
+ clkid = CLOCK_INVALID;
if (timestamping == TS_SOFTWARE || timestamping == TS_LEGACY_HW) {
c->utc_timescale = 1;
}
} else if (phc_index >= 0) {
snprintf(phc, 31, "/dev/ptp%d", phc_index);
- c->clkid = phc_open(phc);
- if (c->clkid == CLOCK_INVALID) {
+ clkid = phc_open(phc);
+ if (clkid == CLOCK_INVALID) {
pr_err("Failed to open %s: %m", phc);
return NULL;
}
- max_adj = phc_max_adj(c->clkid);
+ max_adj = phc_max_adj(clkid);
if (!max_adj) {
pr_err("clock is not adjustable");
return NULL;
}
- clockadj_init(c->clkid);
+ clockadj_init(clkid);
} else {
- c->clkid = CLOCK_REALTIME;
+ clkid = CLOCK_REALTIME;
c->utc_timescale = 1;
- clockadj_init(c->clkid);
+ clockadj_init(clkid);
max_adj = sysclk_max_freq();
sysclk_set_leap(0);
}
@@ -844,12 +841,12 @@ struct clock *clock_create(int phc_index, struct interfaces_head *ifaces,
c->leap_set = 0;
c->time_flags = c->utc_timescale ? 0 : PTP_TIMESCALE;
- if (c->clkid != CLOCK_INVALID) {
- fadj = (int) clockadj_get_freq(c->clkid);
+ if (clkid != CLOCK_INVALID) {
+ fadj = (int) clockadj_get_freq(clkid);
/* Due to a bug in older kernels, the reading may silently fail
and return 0. Set the frequency back to make sure fadj is
the actual frequency of the clock. */
- clockadj_set_freq(c->clkid, fadj);
+ clockadj_set_freq(clkid, fadj);
}
c->servo = servo_create(servo, -fadj, max_adj, sw_ts);
if (!c->servo) {
@@ -902,7 +899,7 @@ struct clock *clock_create(int phc_index, struct interfaces_head *ifaces,
pr_err("failed to allocate pollfd");
return NULL;
}
- c->uds_port = port_open(phc_index, timestamping, 0, udsif, c);
+ c->uds_port = port_open(clkid, phc_index, timestamping, 0, udsif, c);
if (!c->uds_port) {
pr_err("failed to open the UDS port");
return NULL;
@@ -911,7 +908,7 @@ struct clock *clock_create(int phc_index, struct interfaces_head *ifaces,
/* Create the ports. */
STAILQ_FOREACH(iface, ifaces, list) {
- if (clock_add_port(c, phc_index, timestamping, iface)) {
+ if (clock_add_port(c, clkid, phc_index, timestamping, iface)) {
pr_err("failed to open port %s", iface->name);
return NULL;
}
@@ -1354,6 +1351,7 @@ UInteger16 clock_steps_removed(struct clock *c)
}
enum servo_state clock_synchronize(struct clock *c,
+ clockid_t clkid,
struct timespec ingress_ts,
struct timestamp origin_ts,
Integer64 correction1,
@@ -1381,7 +1379,7 @@ enum servo_state clock_synchronize(struct clock *c,
if (!c->path_delay)
return state;
- if (clock_utc_correct(c, ingress))
+ if (clock_utc_correct(c, clkid, ingress))
return c->servo_state;
c->cur.offsetFromMaster = tmv_to_TimeInterval(c->master_offset);
@@ -1407,8 +1405,8 @@ enum servo_state clock_synchronize(struct clock *c,
case SERVO_UNLOCKED:
break;
case SERVO_JUMP:
- clockadj_set_freq(c->clkid, -adj);
- clockadj_step(c->clkid, -tmv_to_nanoseconds(c->master_offset));
+ clockadj_set_freq(clkid, -adj);
+ clockadj_step(clkid, -tmv_to_nanoseconds(c->master_offset));
c->t1 = tmv_zero();
c->t2 = tmv_zero();
if (c->sanity_check) {
@@ -1418,8 +1416,8 @@ enum servo_state clock_synchronize(struct clock *c,
}
break;
case SERVO_LOCKED:
- clockadj_set_freq(c->clkid, -adj);
- if (c->clkid == CLOCK_REALTIME)
+ clockadj_set_freq(clkid, -adj);
+ if (clkid == CLOCK_REALTIME)
sysclk_set_sync();
if (c->sanity_check)
clockcheck_set_freq(c->sanity_check, -adj);
diff --git a/clock.h b/clock.h
index a2b46be..b5ddd38 100644
--- a/clock.h
+++ b/clock.h
@@ -207,6 +207,7 @@ UInteger16 clock_steps_removed(struct clock *c);
/**
* Provide a data point to synchronize the clock.
* @param c The clock instance to synchronize.
+ * @param clkid The posix clock ID to synchronize.
* @param ingress_ts The ingress time stamp on the sync message.
* @param origin_ts The reported transmission time of the sync message.
* @param correction1 The correction field of the sync message.
@@ -215,6 +216,7 @@ UInteger16 clock_steps_removed(struct clock *c);
* @return The state of the clock's servo.
*/
enum servo_state clock_synchronize(struct clock *c,
+ clockid_t clkid,
struct timespec ingress_ts,
struct timestamp origin_ts,
Integer64 correction1,
diff --git a/port.c b/port.c
index f39ad1e..2176962 100644
--- a/port.c
+++ b/port.c
@@ -64,6 +64,7 @@ struct port {
LIST_ENTRY(port) list;
char *name;
struct clock *clock;
+ clockid_t clkid;
struct transport *trp;
enum timestamp_type timestamping;
struct fdarray fda;
@@ -990,7 +991,7 @@ static void port_synchronize(struct port *p,
port_set_sync_rx_tmo(p);
- state = clock_synchronize(p->clock, ingress_ts, origin_ts,
+ state = clock_synchronize(p->clock, p->clkid, ingress_ts, origin_ts,
correction1, correction2);
switch (state) {
case SERVO_UNLOCKED:
@@ -2441,7 +2442,8 @@ err:
msg_put(msg);
}
-struct port *port_open(int phc_index,
+struct port *port_open(clockid_t clkid,
+ int phc_index,
enum timestamp_type timestamping,
int number,
struct interface *interface,
@@ -2454,6 +2456,8 @@ struct port *port_open(int phc_index,
memset(p, 0, sizeof(*p));
+ p->clkid = clkid;
+
if (interface->transport == TRANS_UDS)
; /* UDS cannot have a PHC. */
else if (!interface->ts_info.valid)
diff --git a/port.h b/port.h
index 662eaef..b5b9841 100644
--- a/port.h
+++ b/port.h
@@ -187,6 +187,7 @@ void port_notify_event(struct port *p, enum notification event);
/**
* Open a network port.
+ * @param clkid The posix clock ID for this node.
* @param phc_index The PHC device index for the network device.
* @param timestamping The timestamping mode for this port.
* @param number An arbitrary number assigned to this port.
@@ -194,7 +195,8 @@ void port_notify_event(struct port *p, enum notification event);
* @param clock A pointer to the system PTP clock.
* @return A pointer to an open port on success, or NULL otherwise.
*/
-struct port *port_open(int phc_index,
+struct port *port_open(clockid_t clkid,
+ int phc_index,
enum timestamp_type timestamping,
int number,
struct interface *interface,
--
1.7.10.4
------------------------------------------------------------------------------