During a timer handling we should avoid to call timerfd_settime() on a different timer because this call will invalidate the file descriptor, resulting in a EGAIN when the other timer code will performe the read().
The ANNOUNCE and RX SYNC timer code just doesn't follow this rule. The solution is to split the rearm code. Signed-off-by: Luigi Mantellini <luigi.mantell...@sm-optics.com> --- e2e_tc.c | 26 ++++++++++++++++-------- p2p_tc.c | 26 ++++++++++++++++-------- port.c | 60 ++++++++++++++++++++++++++++++++------------------------ 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/e2e_tc.c b/e2e_tc.c index 43c69e9..c7cfd9e 100644 --- a/e2e_tc.c +++ b/e2e_tc.c @@ -74,6 +74,15 @@ void e2e_dispatch(struct port *p, enum fsm_event event, int mdiff) }; } +static enum fsm_event e2e_announce_sync_rx_timeout_action(struct port *p) +{ + if (p->best) { + fc_clear(p->best); + } + port_set_announce_tmo(p); + return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; +} + enum fsm_event e2e_event(struct port *p, int fd_index) { int cnt, fd = p->fda.fd[fd_index]; @@ -82,15 +91,16 @@ enum fsm_event e2e_event(struct port *p, int fd_index) switch (fd_index) { case FD_ANNOUNCE_TIMER: + pr_debug("%s: announce timeout", p->log_name); + timerfd_flush(p, fd, "announce"); + + return e2e_announce_sync_rx_timeout_action(p); + case FD_SYNC_RX_TIMER: - pr_debug("%s: %s timeout", p->log_name, - fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - timerfd_flush(p, fd, fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - if (p->best) { - fc_clear(p->best); - } - port_set_announce_tmo(p); - return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; + pr_debug("%s: rx sync timeout", p->log_name); + timerfd_flush(p, fd, "rx sync"); + + return e2e_announce_sync_rx_timeout_action(p); case FD_DELAY_TIMER: pr_debug("%s: delay timeout", p->log_name); diff --git a/p2p_tc.c b/p2p_tc.c index 55a4b1c..0d6d68b 100644 --- a/p2p_tc.c +++ b/p2p_tc.c @@ -90,6 +90,15 @@ void p2p_dispatch(struct port *p, enum fsm_event event, int mdiff) }; } +static enum fsm_event p2p_announce_sync_rx_timeout_action(struct port *p) +{ + if (p->best) { + fc_clear(p->best); + } + port_set_announce_tmo(p); + return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; +} + enum fsm_event p2p_event(struct port *p, int fd_index) { int cnt, fd = p->fda.fd[fd_index]; @@ -98,15 +107,16 @@ enum fsm_event p2p_event(struct port *p, int fd_index) switch (fd_index) { case FD_ANNOUNCE_TIMER: + pr_debug("%s: announce timeout", p->log_name); + timerfd_flush(p, fd, "announce"); + + return p2p_announce_sync_rx_timeout_action(p); + case FD_SYNC_RX_TIMER: - pr_debug("%s: %s timeout", p->log_name, - fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - timerfd_flush(p, fd, fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - if (p->best) { - fc_clear(p->best); - } - port_set_announce_tmo(p); - return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; + pr_debug("%s: rx sync timeout", p->log_name); + timerfd_flush(p, fd, "rx sync"); + + return p2p_announce_sync_rx_timeout_action(p); case FD_DELAY_TIMER: pr_debug("%s: delay timeout", p->log_name); diff --git a/port.c b/port.c index 1f520b0..7609f2c 100644 --- a/port.c +++ b/port.c @@ -2842,6 +2842,24 @@ enum fsm_event port_event(struct port *p, int fd_index) return p->event(p, fd_index); } +static enum fsm_event bc_announce_sync_rx_timeout_action(struct port *p) +{ + if (p->best) { + fc_clear(p->best); + } + + delay_req_prune(p); + if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && + port_renew_transport(p)) { + return EV_FAULT_DETECTED; + } + + if (p->inhibit_announce) { + return EV_NONE; + } + return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; +} + static enum fsm_event bc_event(struct port *p, int fd_index) { enum fsm_event event = EV_NONE; @@ -2850,20 +2868,25 @@ static enum fsm_event bc_event(struct port *p, int fd_index) switch (fd_index) { case FD_ANNOUNCE_TIMER: - case FD_SYNC_RX_TIMER: - pr_debug("%s: %s timeout", p->log_name, - fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - timerfd_flush(p, fd, fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - if (p->best) { - fc_clear(p->best); - } + pr_debug("%s: announce timeout", p->log_name); + timerfd_flush(p, fd, "announce"); + + p->service_stats.announce_timeout++; - if (fd_index == FD_SYNC_RX_TIMER) { - p->service_stats.sync_timeout++; + if (p->inhibit_announce) { + port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); } else { - p->service_stats.announce_timeout++; + port_set_announce_tmo(p); } + return bc_announce_sync_rx_timeout_action(p); + + case FD_SYNC_RX_TIMER: + pr_debug("%s: rx sync timeout", p->log_name); + timerfd_flush(p, fd, "rx sync"); + + p->service_stats.sync_timeout++; + /* * Clear out the event returned by poll(). It is only cleared * in port_*_transition(). But, when BMCA == 'noop', there is no @@ -2873,22 +2896,7 @@ static enum fsm_event bc_event(struct port *p, int fd_index) port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); } - if (p->inhibit_announce) { - port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); - } else { - port_set_announce_tmo(p); - } - - delay_req_prune(p); - if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && - port_renew_transport(p)) { - return EV_FAULT_DETECTED; - } - - if (p->inhibit_announce) { - return EV_NONE; - } - return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; + return bc_announce_sync_rx_timeout_action(p); case FD_DELAY_TIMER: pr_debug("%s: delay timeout", p->log_name); -- 2.40.0 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel