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

Problem
=======
Unselected master port may unintentionally continue to request 
announce/sync/delay_resp packets. Expecting port with unselected master
to only maintain announce messages.

Cause
=====
In handle_state_decision_event() loop, the update of the clock's parent pid
to reflect best master change is non-deterministic. It depends on the port
processing order and bmc_state_decision() results.

However, port_dispatch() called at the end of each loop iteration will use
the clock's parent pid in subsequent unicast_client_state_changed() to
drive the unicast FSM.

If the clock parent pid is not updated properly prior to
unicast_client_state_changed(), the unicast FSM may not
transition properly.


Solution v2
===========
Refactor port_state_update() to mark unicast_state_dirty instead
of calling unicast_client_state_changed(). 
Add new port loop after handle_state_decision_event() port loop
to call unicast_client_state_changed() after all necessary 
parent pid has been updated.


Signed-off-by: Vincent Cheng <vincent.cheng...@renesas.com>
---
 clock.c        |  6 ++++++
 port.c         | 12 ++++++++++--
 port.h         |  7 +++++++
 port_private.h |  1 +
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clock.c b/clock.c
index 134c7c3..a68a732 100644
--- a/clock.c
+++ b/clock.c
@@ -669,7 +669,9 @@ static void clock_update_grandmaster(struct clock *c)
        struct parentDS *pds = &c->dad.pds;
        memset(&c->cur, 0, sizeof(c->cur));
        memset(c->ptl, 0, sizeof(c->ptl));
+
        pds->parentPortIdentity.clockIdentity   = c->dds.clockIdentity;
+       /* Follow IEEE 1588 Table 30: Updates for state decision code M1 and M2 
*/
        pds->parentPortIdentity.portNumber      = 0;
        pds->grandmasterIdentity                = c->dds.clockIdentity;
        pds->grandmasterClockQuality            = c->dds.clockQuality;
@@ -2049,6 +2051,10 @@ static void handle_state_decision_event(struct clock *c)
                }
                port_dispatch(piter, event, fresh_best);
        }
+
+       LIST_FOREACH(piter, &c->ports, list) {
+               port_update_unicast_state(piter);
+       }
 }
 
 struct clock_description *clock_description(struct clock *c)
diff --git a/port.c b/port.c
index 6baf5c8..c8cba5b 100644
--- a/port.c
+++ b/port.c
@@ -3445,13 +3445,13 @@ int port_state_update(struct port *p, enum fsm_event 
event, int mdiff)
        }
 
        if (mdiff) {
-               unicast_client_state_changed(p);
+               p->unicast_state_dirty = true;
        }
        if (next != p->state) {
                port_show_transition(p, next, event);
                p->state = next;
                port_notify_event(p, NOTIFY_PORT_STATE);
-               unicast_client_state_changed(p);
+               p->unicast_state_dirty = true;
                return 1;
        }
 
@@ -3462,3 +3462,11 @@ enum bmca_select port_bmca(struct port *p)
 {
        return p->bmca;
 }
+
+void port_update_unicast_state(struct port *p)
+{
+       if (p->unicast_state_dirty) {
+               unicast_client_state_changed(p);
+               p->unicast_state_dirty = false;
+       }
+}
diff --git a/port.h b/port.h
index 4854698..57c8c2f 100644
--- a/port.h
+++ b/port.h
@@ -357,4 +357,11 @@ enum bmca_select port_bmca(struct port *p);
  */
 void tc_cleanup(void);
 
+/**
+ * Update port's unicast state if port's unicast_state_dirty is true.
+ *
+ * @param port  A port instance.
+ */
+void port_update_unicast_state(struct port *p);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..13a6c6a 100644
--- a/port_private.h
+++ b/port_private.h
@@ -158,6 +158,7 @@ struct port {
        int inhibit_multicast_service;
        /* slave event monitoring */
        struct monitor *slave_event_monitor;
+       bool unicast_state_dirty;
 };
 
 #define portnum(p) (p->portIdentity.portNumber)
-- 
2.34.1



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

Reply via email to