Backport of commit 73318c5b99571c8da01474ad665e2e2e06ab12bb Author: Richard Cochran Date: Sun Feb 5 18:31:27 2017 +0100 clock: Force a BMC election when a port link goes down. Having one fewer port may affect the result of the BMCA. This patch changes the main loop so that a link down event also causes a state decision event. Signed-off-by: Richard Cochran Reported-by: Henry Jesuiter diff -up linuxptp-1.8/clock.c.linkdown linuxptp-1.8/clock.c --- linuxptp-1.8/clock.c.linkdown 2017-03-15 08:37:03.017542152 +0100 +++ linuxptp-1.8/clock.c 2017-03-15 08:42:53.238682318 +0100 @@ -96,6 +96,7 @@ struct clock { int pollfd_valid; int nports; /* does not include the UDS port */ int last_port_number; + int sde; struct hash *index2port; int free_running; int freq_est_interval; @@ -341,6 +342,11 @@ static void clock_link_status(void *ctx, port_dispatch(p, EV_FAULT_CLEARED, 0); } else { port_dispatch(p, EV_FAULT_DETECTED, 0); + /* + * A port going down can affect the BMCA result. + * Force a state decision event. + */ + c->sde = 1; } } @@ -1465,7 +1471,7 @@ struct PortIdentity clock_parent_identit int clock_poll(struct clock *c) { - int cnt, err, i, sde = 0; + int cnt, err, i; enum fsm_event event; struct pollfd *cur; struct port *p; @@ -1496,9 +1502,9 @@ int clock_poll(struct clock *c) if (cur[i].revents & (POLLIN|POLLPRI)) { event = port_event(p, i); if (EV_STATE_DECISION_EVENT == event) - sde = 1; + c->sde = 1; if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == event) - sde = 1; + c->sde = 1; err = port_dispatch(p, event, 0); /* Clear any fault after a little while. */ if (PS_FAULTY == port_state(p)) { @@ -1527,13 +1533,14 @@ int clock_poll(struct clock *c) if (cur[i].revents & (POLLIN|POLLPRI)) { event = port_event(c->uds_port, i); if (EV_STATE_DECISION_EVENT == event) - sde = 1; + c->sde = 1; } } - if (sde) + if (c->sde) { handle_state_decision_event(c); - + c->sde = 0; + } clock_prune_subscriptions(c); return 0; }