refresh link status on faults (RHEL-89811)
Resolves: RHEL-89811
This commit is contained in:
parent
040812da63
commit
c5d125c9d0
75
linuxptp-rtnlinit.patch
Normal file
75
linuxptp-rtnlinit.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
commit 01de33e91f9717d0cbae5af6eee2beb45deee219
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Tue Mar 4 15:53:37 2025 +0100
|
||||||
|
|
||||||
|
port: Refresh link status on faults.
|
||||||
|
|
||||||
|
ptp4l gets the ENOBUFS error on the netlink socket when the kernel has
|
||||||
|
to drop messages due to full socket buffer. If ptp4l has a port in the
|
||||||
|
faulty state waiting for the link to go up and that event corresponds
|
||||||
|
to one of the dropped netlink messages, the port will be stuck in the
|
||||||
|
faulty state until the link goes down and up again.
|
||||||
|
|
||||||
|
To prevent the port from getting stuck, request the current link status
|
||||||
|
when dispatching the EV_FAULT_DETECTED event. Also, reopen the socket to
|
||||||
|
get rid of the buffered messages when handling the fault and again when
|
||||||
|
reinitializing the port.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
|
||||||
|
diff --git a/port.c b/port.c
|
||||||
|
index 7f945ac..1bb407c 100644
|
||||||
|
--- a/port.c
|
||||||
|
+++ b/port.c
|
||||||
|
@@ -1975,6 +1975,20 @@ static int port_cmlds_initialize(struct port *p)
|
||||||
|
return port_cmlds_renew(p, now.tv_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void port_rtnl_initialize(struct port *p)
|
||||||
|
+{
|
||||||
|
+ /* Reopen the socket to get rid of buffered messages */
|
||||||
|
+ if (p->fda.fd[FD_RTNL] >= 0) {
|
||||||
|
+ rtnl_close(p->fda.fd[FD_RTNL]);
|
||||||
|
+ }
|
||||||
|
+ p->fda.fd[FD_RTNL] = rtnl_open();
|
||||||
|
+ if (p->fda.fd[FD_RTNL] >= 0) {
|
||||||
|
+ rtnl_link_query(p->fda.fd[FD_RTNL], interface_name(p->iface));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ clock_fda_changed(p->clock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void port_disable(struct port *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
@@ -2087,13 +2101,8 @@ int port_initialize(struct port *p)
|
||||||
|
if (p->bmca == BMCA_NOOP) {
|
||||||
|
port_set_delay_tmo(p);
|
||||||
|
}
|
||||||
|
- if (p->fda.fd[FD_RTNL] == -1) {
|
||||||
|
- p->fda.fd[FD_RTNL] = rtnl_open();
|
||||||
|
- }
|
||||||
|
- if (p->fda.fd[FD_RTNL] >= 0) {
|
||||||
|
- const char *ifname = interface_name(p->iface);
|
||||||
|
- rtnl_link_query(p->fda.fd[FD_RTNL], ifname);
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ port_rtnl_initialize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
port_nrate_initialize(p);
|
||||||
|
@@ -3768,6 +3777,13 @@ int port_state_update(struct port *p, enum fsm_event event, int mdiff)
|
||||||
|
if (port_link_status_get(p) && clear_fault_asap(&i)) {
|
||||||
|
pr_notice("%s: clearing fault immediately", p->log_name);
|
||||||
|
next = p->state_machine(next, EV_FAULT_CLEARED, 0);
|
||||||
|
+ } else if (event == EV_FAULT_DETECTED) {
|
||||||
|
+ /*
|
||||||
|
+ * Reopen the netlink socket and refresh the link
|
||||||
|
+ * status in case the fault was triggered by a missed
|
||||||
|
+ * netlink message (ENOBUFS).
|
||||||
|
+ */
|
||||||
|
+ port_rtnl_initialize(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,6 +39,8 @@ Patch4: linuxptp-nowait.patch
|
|||||||
Patch8: linuxptp-externalpps.patch
|
Patch8: linuxptp-externalpps.patch
|
||||||
# add command to set external grandmaster properties
|
# add command to set external grandmaster properties
|
||||||
Patch9: linuxptp-externalgm.patch
|
Patch9: linuxptp-externalgm.patch
|
||||||
|
# refresh link status on faults
|
||||||
|
Patch10: linuxptp-rtnlinit.patch
|
||||||
|
|
||||||
BuildRequires: gcc gcc-c++ gnutls-devel make systemd
|
BuildRequires: gcc gcc-c++ gnutls-devel make systemd
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user