integ/base/linuxptp/debian/patches/0025-pmc_agent-Rename-the-update-method-and-attempt-to-do.patch
Cole Walker aca42c6d4c Implement logic to skip updates with offset spike in ts2phc.
This change allows ts2phc to be configured to ignore timing updates that
have a large offset spike in order to mitigate the resulting timing
skew.

In some circumstances on realtime systems with high CPU load, the
timestamp consumed by ts2phc can be delayed in reaching ts2phc and
results in the offset calculation attempting to speed the clock up by a
large margin.

This change causes ts2phc to ignore updates that would greatly skew the
clock when ts2phc is already in a synchronized state.

The global configuration option "max_phc_update_skip_cnt" is provided to
allow users to specify how many consecutive offset spike incidents will
be ignored before adjusting the clock. The default value is 120. The
behaviour can be disabled by setting max_phc_update_skip_cnt to 0.

This code is ported from a proposed upstream patch found here:
https://sourceforge.net/p/linuxptp/mailman/message/44114092/

Test-plan:
Pass: Verify linuxptp package build
Pass: Deploy ts2phc binary and verify system time sync
Pass: Manually trigger offset spike and verify that ts2phc maintains
stable time sync

Closes-bug: https://bugs.launchpad.net/starlingx/+bug/2059955

Change-Id: I13cd5c3440682ec9256e11449fe62d5fe28f66fa
Signed-off-by: Cole Walker <cole.walker@windriver.com>
2024-04-01 14:53:06 -04:00

156 lines
4.7 KiB
Diff

From 9136345c69038a22d9b548863fb6afe64e54958d Mon Sep 17 00:00:00 2001
From: Andre Mauricio Zelak <andre.zelak@windriver.com>
Date: Mon, 12 Jun 2023 15:36:38 -0300
Subject: [PATCH 25/58] pmc_agent: Rename the update method and attempt to
document it.
This patch renames the function to have the module prefix and tries to
put into words what it does.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
[commit 9a2dae984e0d355d751913e3308f9a954da11aa3 upstream]
Signed-off-by: Andre Mauricio Zelak <andre.zelak@windriver.com>
---
phc2sys.c | 4 ++--
pmc_agent.c | 53 ++++++++++++++++++++++++++---------------------------
pmc_agent.h | 21 ++++++++++++++++++++-
3 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/phc2sys.c b/phc2sys.c
index b155961..cbe80f2 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -672,7 +672,7 @@ static int do_pps_loop(struct phc2sys_private *priv, struct clock *clock,
pps_offset = pps_ts - phc_ts;
}
- if (update_pmc_node(priv->node) < 0)
+ if (pmc_agent_update(priv->node) < 0)
continue;
update_clock(priv, clock, pps_offset, pps_ts, -1);
}
@@ -711,7 +711,7 @@ static int do_loop(struct phc2sys_private *priv, int subscriptions)
while (is_running()) {
clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL);
- if (update_pmc_node(priv->node) < 0) {
+ if (pmc_agent_update(priv->node) < 0) {
continue;
}
diff --git a/pmc_agent.c b/pmc_agent.c
index ea6b3b7..22af306 100644
--- a/pmc_agent.c
+++ b/pmc_agent.c
@@ -336,33 +336,6 @@ int run_pmc_clock_identity(struct pmc_agent *node, int timeout)
return 1;
}
-/* Returns: -1 in case of error, 0 otherwise */
-int update_pmc_node(struct pmc_agent *node)
-{
- struct timespec tp;
- uint64_t ts;
-
- if (!node->pmc) {
- return 0;
- }
- if (clock_gettime(CLOCK_MONOTONIC, &tp)) {
- pr_err("failed to read clock: %m");
- return -1;
- }
- ts = tp.tv_sec * NS_PER_SEC + tp.tv_nsec;
-
- if (ts - node->pmc_last_update >= PMC_UPDATE_INTERVAL) {
- if (node->stay_subscribed) {
- renew_subscription(node, 0);
- }
- if (run_pmc_get_utc_offset(node, 0) > 0) {
- node->pmc_last_update = ts;
- }
- }
-
- return 0;
-}
-
int init_pmc_node(struct config *cfg, struct pmc_agent *node, const char *uds,
pmc_node_recv_subscribed_t *recv_subscribed, void *context)
{
@@ -414,6 +387,32 @@ int pmc_agent_subscribe(struct pmc_agent *node, int timeout)
return renew_subscription(node, timeout);
}
+int pmc_agent_update(struct pmc_agent *node)
+{
+ struct timespec tp;
+ uint64_t ts;
+
+ if (!node->pmc) {
+ return 0;
+ }
+ if (clock_gettime(CLOCK_MONOTONIC, &tp)) {
+ pr_err("failed to read clock: %m");
+ return -errno;
+ }
+ ts = tp.tv_sec * NS_PER_SEC + tp.tv_nsec;
+
+ if (ts - node->pmc_last_update >= PMC_UPDATE_INTERVAL) {
+ if (node->stay_subscribed) {
+ renew_subscription(node, 0);
+ }
+ if (run_pmc_get_utc_offset(node, 0) > 0) {
+ node->pmc_last_update = ts;
+ }
+ }
+
+ return 0;
+}
+
bool pmc_agent_utc_offset_traceable(struct pmc_agent *agent)
{
return agent->utc_offset_traceable;
diff --git a/pmc_agent.h b/pmc_agent.h
index 743818f..483a21b 100644
--- a/pmc_agent.h
+++ b/pmc_agent.h
@@ -33,7 +33,6 @@ typedef int pmc_node_recv_subscribed_t(void *context, struct ptp_message *msg,
int init_pmc_node(struct config *cfg, struct pmc_agent *agent, const char *uds,
pmc_node_recv_subscribed_t *recv_subscribed, void *context);
-int update_pmc_node(struct pmc_agent *agent);
int run_pmc_clock_identity(struct pmc_agent *agent, int timeout);
int run_pmc_wait_sync(struct pmc_agent *agent, int timeout);
int run_pmc_get_number_ports(struct pmc_agent *agent, int timeout);
@@ -85,6 +84,26 @@ void pmc_agent_set_sync_offset(struct pmc_agent *agent, int offset);
*/
int pmc_agent_subscribe(struct pmc_agent *agent, int timeout);
+/**
+ * Queries the local ptp4l instance to update the TAI-UTC offset and
+ * the current leap second flags.
+ *
+ * In addition:
+ *
+ * - Any active port state subscription will be renewed.
+ * - The port state notification callback might be invoked.
+ *
+ * This function should be called periodically at least once per
+ * minute to keep both the port state and the leap second flags up to
+ * date. Note that the PMC agent rate limits the query to once per
+ * minute, and so the caller may safely invoke this method more often
+ * than that.
+ *
+ * @param agent Pointer to a PMC instance obtained via @ref pmc_agent_create().
+ * @return Zero on success, negative error code otherwise.
+ */
+int pmc_agent_update(struct pmc_agent *agent);
+
/**
* Tests whether the current UTC offset is traceable.
* @param agent Pointer to a PMC instance obtained via @ref pmc_agent_create().
--
2.30.2