patches for DPDK stable branches
 help / color / mirror / Atom feed
* [PATCH 19.11 0/3] net/mlx5: fix link state detection
@ 2022-03-11  8:06 Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 1/3] common/mlx5: add Netlink event helpers Dmitry Kozlyuk
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Dmitry Kozlyuk @ 2022-03-11  8:06 UTC (permalink / raw)
  To: stable; +Cc: Christian Ehrhardt

[ backport of https://inbox.dpdk.org/dev/20220301121514.41497-1-dkozlyuk@nvidia.com ]

This patchset fixes two related issues:
* In rare occasions with any HW link state change to UP was missed.
* If a port was DOWN before startup, its netdev would come UP,
  but appear DOWN in DPDK (especially probable with ConnectX-4).

Dmitry Kozlyuk (3):
  common/mlx5: add Netlink event helpers
  net/mlx5: fix link status change detection
  net/mlx5: fix initial link status detection

 drivers/net/mlx5/mlx5.c         |  59 +++++++++++++++---
 drivers/net/mlx5/mlx5.h         |  10 ++-
 drivers/net/mlx5/mlx5_ethdev.c  |  63 +++++++++++++++----
 drivers/net/mlx5/mlx5_nl.c      | 107 +++++++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_trigger.c |  12 +++-
 5 files changed, 224 insertions(+), 27 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 19.11 1/3] common/mlx5: add Netlink event helpers
  2022-03-11  8:06 [PATCH 19.11 0/3] net/mlx5: fix link state detection Dmitry Kozlyuk
@ 2022-03-11  8:06 ` Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 2/3] net/mlx5: fix link status change detection Dmitry Kozlyuk
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Dmitry Kozlyuk @ 2022-03-11  8:06 UTC (permalink / raw)
  To: stable; +Cc: Christian Ehrhardt, Viacheslav Ovsiienko

[ upstream commit be66461cba371c3138ce942eb9fe5657f9e9a446 ]

Introduce mlx5_nl_read_events() to read Netlink events
(technically, messages) from a socket that was configured
to listen for them via a new mlx5_nl_init() parameter.
Add mlx5_nl_parse_link_status_update() helper
to extract information from link-related events.
This patch is a shared base for later fixes.

Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Reviewed-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5.c    |   8 +--
 drivers/net/mlx5/mlx5.h    |   7 ++-
 drivers/net/mlx5/mlx5_nl.c | 107 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 115 insertions(+), 7 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index d9db6aa398..27e04b5d9e 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2433,8 +2433,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	priv->pci_dev = spawn->pci_dev;
 	priv->mtu = RTE_ETHER_MTU;
 	/* Some internal functions rely on Netlink sockets, open them now. */
-	priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA);
-	priv->nl_socket_route =	mlx5_nl_init(NETLINK_ROUTE);
+	priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA, 0);
+	priv->nl_socket_route =	mlx5_nl_init(NETLINK_ROUTE, 0);
 	priv->nl_sn = 0;
 	priv->representor = !!switch_info->representor;
 	priv->master = !!switch_info->master;
@@ -3105,8 +3105,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	 * matching ones, gathering into the list.
 	 */
 	struct ibv_device *ibv_match[ret + 1];
-	int nl_route = mlx5_nl_init(NETLINK_ROUTE);
-	int nl_rdma = mlx5_nl_init(NETLINK_RDMA);
+	int nl_route = mlx5_nl_init(NETLINK_ROUTE, 0);
+	int nl_rdma = mlx5_nl_init(NETLINK_RDMA, 0);
 	unsigned int i;
 
 	while (ret-- > 0) {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b2dc9e291b..b74f1bbc83 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -12,6 +12,7 @@
 #include <limits.h>
 #include <net/if.h>
 #include <netinet/in.h>
+#include <netlink/netlink.h>
 #include <sys/queue.h>
 
 /* Verbs header. */
@@ -991,7 +992,9 @@ void mlx5_mp_uninit_secondary(void);
 
 /* mlx5_nl.c */
 
-int mlx5_nl_init(int protocol);
+typedef void (mlx5_nl_event_cb)(struct nlmsghdr *hdr, void *user_data);
+
+int mlx5_nl_init(int protocol, int groups);
 int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
 			 uint32_t index);
 int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
@@ -1006,6 +1009,8 @@ int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev,
 			       struct rte_ether_addr *mac, int vf_index);
 int mlx5_nl_switch_info(int nl, unsigned int ifindex,
 			struct mlx5_switch_info *info);
+int mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg);
+int mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex);
 
 struct mlx5_vlan_vmwa_context *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,
 						   uint32_t ifindex);
diff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c
index 668affb0b1..2564e8779b 100644
--- a/drivers/net/mlx5/mlx5_nl.c
+++ b/drivers/net/mlx5/mlx5_nl.c
@@ -119,19 +119,22 @@ struct mlx5_nl_ifindex_data {
  *
  * @param protocol
  *   Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA).
+ * @param groups
+ *   Groups to listen (e.g. RTMGRP_LINK), can be 0.
  *
  * @return
  *   A file descriptor on success, a negative errno value otherwise and
  *   rte_errno is set.
  */
 int
-mlx5_nl_init(int protocol)
+mlx5_nl_init(int protocol, int groups)
 {
 	int fd;
 	int sndbuf_size = MLX5_SEND_BUF_SIZE;
 	int rcvbuf_size = MLX5_RECV_BUF_SIZE;
 	struct sockaddr_nl local = {
 		.nl_family = AF_NETLINK,
+		.nl_groups = groups,
 	};
 	int ret;
 
@@ -1400,7 +1403,7 @@ mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,
 			" for VLAN workaround context");
 		return NULL;
 	}
-	vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE);
+	vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE, 0);
 	if (vmwa->nl_socket < 0) {
 		DRV_LOG(WARNING,
 			"Can not create Netlink socket"
@@ -1431,3 +1434,103 @@ void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *vmwa)
 		close(vmwa->nl_socket);
 	rte_free(vmwa);
 }
+
+/**
+ * Try to parse a Netlink message as a link status update.
+ *
+ * @param hdr
+ *  Netlink message header.
+ * @param[out] ifindex
+ *  Index of the updated interface.
+ * @param[out] flags
+ *  New interface flags.
+ *
+ * @return
+ *  0 on success, negative on failure.
+ */
+int
+mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex)
+{
+	struct ifinfomsg *info;
+
+	switch (hdr->nlmsg_type) {
+	case RTM_NEWLINK:
+	case RTM_DELLINK:
+	case RTM_GETLINK:
+	case RTM_SETLINK:
+		info = NLMSG_DATA(hdr);
+		*ifindex = info->ifi_index;
+		return 0;
+	}
+	return -1;
+}
+
+/**
+ * Read pending events from a Netlink socket.
+ *
+ * @param nlsk_fd
+ *  Netlink socket.
+ * @param cb
+ *  Callback invoked for each of the events.
+ * @param cb_arg
+ *  User data for the callback.
+ *
+ * @return
+ *  0 on success, including the case when there are no events.
+ *  Negative on failure and rte_errno is set.
+ */
+int
+mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg)
+{
+	char buf[8192];
+	struct sockaddr_nl addr;
+	struct iovec iov = {
+		.iov_base = buf,
+		.iov_len = sizeof(buf),
+	};
+	struct msghdr msg = {
+		.msg_name = &addr,
+		.msg_namelen = sizeof(addr),
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+	};
+	struct nlmsghdr *hdr;
+	ssize_t size;
+
+	while (1) {
+		size = recvmsg(nlsk_fd, &msg, MSG_DONTWAIT);
+		if (size < 0) {
+			if (errno == EAGAIN)
+				return 0;
+			if (errno == EINTR)
+				continue;
+			DRV_LOG(DEBUG, "Failed to receive netlink message: %s",
+				strerror(errno));
+			rte_errno = errno;
+			return -rte_errno;
+
+		}
+		hdr = (struct nlmsghdr *)buf;
+		while (size >= (ssize_t)sizeof(*hdr)) {
+			ssize_t msg_len = hdr->nlmsg_len;
+			ssize_t data_len = msg_len - sizeof(*hdr);
+			ssize_t aligned_len;
+
+			if (data_len < 0) {
+				DRV_LOG(DEBUG, "Netlink message too short");
+				rte_errno = EINVAL;
+				return -rte_errno;
+			}
+			aligned_len = NLMSG_ALIGN(msg_len);
+			if (aligned_len > size) {
+				DRV_LOG(DEBUG, "Netlink message too long");
+				rte_errno = EINVAL;
+				return -rte_errno;
+			}
+			cb(hdr, cb_arg);
+			hdr = RTE_PTR_ADD(hdr, aligned_len);
+			size -= aligned_len;
+		}
+	}
+	return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 19.11 2/3] net/mlx5: fix link status change detection
  2022-03-11  8:06 [PATCH 19.11 0/3] net/mlx5: fix link state detection Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 1/3] common/mlx5: add Netlink event helpers Dmitry Kozlyuk
@ 2022-03-11  8:06 ` Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 3/3] net/mlx5: fix initial link status detection Dmitry Kozlyuk
  2022-03-11 10:06 ` [PATCH 19.11 0/3] net/mlx5: fix link state detection Christian Ehrhardt
  3 siblings, 0 replies; 5+ messages in thread
From: Dmitry Kozlyuk @ 2022-03-11  8:06 UTC (permalink / raw)
  To: stable; +Cc: Christian Ehrhardt, Viacheslav Ovsiienko

[ upstream commit 17f95513adca1f4ee5bba305b154ac984ee50cee ]

Sometimes net/mlx5 devices did not detect link status change to "up".

Each shared device was monitoring IBV_EVENT_PORT_{ACTIVE,ERR}
and queried the link status upon receiving the event.
IBV_EVENT_PORT_ACTIVE is delivered when the logical link status
(UP flag) is set, but the physical link status (RUNNING flag)
may be down at that time, in which case the new link status
would be errornously considered down.

IBV interface is insufficient for the task.
Monitor interface events using Netlink.

Fixes: 198a3c339a8f ("mlx5: handle link status interrupts")

Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Reviewed-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5.c         | 40 +++++++++++++++++++++
 drivers/net/mlx5/mlx5.h         |  3 ++
 drivers/net/mlx5/mlx5_ethdev.c  | 63 ++++++++++++++++++++++++++-------
 drivers/net/mlx5/mlx5_trigger.c | 12 +++++--
 4 files changed, 104 insertions(+), 14 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 27e04b5d9e..068b0ef981 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -470,6 +470,40 @@ mlx5_restore_doorbell_mapping_env(int value)
 		setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1);
 }
 
+static int
+mlx5_os_dev_shared_handler_install_lsc(struct mlx5_ibv_shared *sh)
+{
+	int nlsk_fd, flags, ret;
+
+	nlsk_fd = mlx5_nl_init(NETLINK_ROUTE, RTMGRP_LINK);
+	if (nlsk_fd < 0) {
+		DRV_LOG(ERR, "Failed to create a socket for Netlink events: %s",
+			rte_strerror(rte_errno));
+		return -1;
+	}
+	flags = fcntl(nlsk_fd, F_GETFL);
+	ret = fcntl(nlsk_fd, F_SETFL, flags | O_NONBLOCK);
+	if (ret != 0) {
+		DRV_LOG(ERR, "Failed to make Netlink event socket non-blocking: %s",
+			strerror(errno));
+		rte_errno = errno;
+		goto error;
+	}
+	sh->intr_handle_nl.type = RTE_INTR_HANDLE_EXT;
+	sh->intr_handle_nl.fd = nlsk_fd;
+	if (rte_intr_callback_register(&sh->intr_handle_nl,
+				       mlx5_dev_interrupt_handler_nl,
+				       sh) != 0) {
+		DRV_LOG(ERR, "Failed to register Netlink events interrupt");
+		sh->intr_handle_nl.fd = -1;
+		goto error;
+	}
+	return 0;
+error:
+	close(nlsk_fd);
+	return -1;
+}
+
 /**
  * Install shared asynchronous device events handler.
  * This function is implemented to support event sharing
@@ -499,6 +533,11 @@ mlx5_dev_shared_handler_install(struct mlx5_ibv_shared *sh)
 			sh->intr_handle.fd = -1;
 		}
 	}
+	sh->intr_handle_nl.fd = -1;
+	if (mlx5_os_dev_shared_handler_install_lsc(sh) < 0) {
+		DRV_LOG(INFO, "Fail to install the shared Netlink event handler.");
+		sh->intr_handle_nl.fd = -1;
+	}
 	if (sh->devx) {
 #ifdef HAVE_IBV_DEVX_ASYNC
 		sh->intr_handle_devx.fd = -1;
@@ -651,6 +690,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
 	for (i = 0; i < sh->max_port; i++) {
 		sh->port[i].ih_port_id = RTE_MAX_ETHPORTS;
 		sh->port[i].devx_ih_port_id = RTE_MAX_ETHPORTS;
+		sh->port[i].nl_ih_port_id = RTE_MAX_ETHPORTS;
 	}
 	sh->pd = mlx5_glue->alloc_pd(sh->ctx);
 	if (sh->pd == NULL) {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b74f1bbc83..1cf5f41689 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -575,6 +575,7 @@ struct mlx5_flow_counter_mng {
 struct mlx5_ibv_shared_port {
 	uint32_t ih_port_id;
 	uint32_t devx_ih_port_id;
+	uint32_t nl_ih_port_id;
 	/*
 	 * Interrupt handler port_id. Used by shared interrupt
 	 * handler to find the corresponding rte_eth device
@@ -693,6 +694,7 @@ struct mlx5_ibv_shared {
 	/* Shared interrupt handler section. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
 	struct rte_intr_handle intr_handle_devx; /* DEVX interrupt handler. */
+	struct rte_intr_handle intr_handle_nl; /* Netlink interrupt handler. */
 	struct mlx5dv_devx_cmd_comp *devx_comp; /* DEVX async comp obj. */
 	struct mlx5_devx_obj *tis; /* TIS object. */
 	struct mlx5_devx_obj *td; /* Transport domain. */
@@ -841,6 +843,7 @@ int mlx5_dev_to_pci_addr(const char *dev_path,
 void mlx5_dev_link_status_handler(void *arg);
 void mlx5_dev_interrupt_handler(void *arg);
 void mlx5_dev_interrupt_handler_devx(void *arg);
+void mlx5_dev_interrupt_handler_nl(void *arg);
 void mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev);
 void mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev);
 int mlx5_set_link_down(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 7af7fb0f9f..5334377c10 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1301,6 +1301,57 @@ mlx5_dev_interrupt_device_fatal(struct mlx5_ibv_shared *sh)
 	}
 }
 
+static void
+mlx5_dev_interrupt_nl_cb(struct nlmsghdr *hdr, void *cb_arg)
+{
+	struct mlx5_ibv_shared *sh = cb_arg;
+	uint32_t i;
+	uint32_t if_index;
+
+	if (mlx5_nl_parse_link_status_update(hdr, &if_index) < 0)
+		return;
+	for (i = 0; i < sh->max_port; i++) {
+		struct mlx5_ibv_shared_port *port = &sh->port[i];
+		struct rte_eth_dev *dev;
+		struct mlx5_priv *priv;
+		bool configured;
+
+		if (port->nl_ih_port_id >= RTE_MAX_ETHPORTS)
+			continue;
+		dev = &rte_eth_devices[port->nl_ih_port_id];
+		configured = dev->process_private != NULL;
+		/* Probing may initiate an LSC before configuration is done. */
+		if (configured && !dev->data->dev_conf.intr_conf.lsc)
+			break;
+		priv = dev->data->dev_private;
+		if (priv->if_index == if_index) {
+			/* Block logical LSC events. */
+			uint16_t prev_status = dev->data->dev_link.link_status;
+
+			if (mlx5_link_update(dev, 0) < 0)
+				DRV_LOG(ERR, "Failed to update link status: %s",
+					rte_strerror(rte_errno));
+			else if (prev_status != dev->data->dev_link.link_status)
+				_rte_eth_dev_callback_process
+					(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+			break;
+		}
+	}
+}
+
+void
+mlx5_dev_interrupt_handler_nl(void *arg)
+{
+	struct mlx5_ibv_shared *sh = arg;
+	int nlsk_fd = sh->intr_handle_nl.fd;
+
+	if (nlsk_fd < 0)
+		return;
+	if (mlx5_nl_read_events(nlsk_fd, mlx5_dev_interrupt_nl_cb, sh) < 0)
+		DRV_LOG(ERR, "Failed to process Netlink events: %s",
+			rte_strerror(rte_errno));
+}
+
 /**
  * Handle shared asynchronous events the NIC (removal event
  * and link status change). Supports multiport IB device.
@@ -1364,18 +1415,6 @@ mlx5_dev_interrupt_handler(void *cb_arg)
 		tmp = sh->port[tmp - 1].ih_port_id;
 		dev = &rte_eth_devices[tmp];
 		assert(dev);
-		if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
-		     event.event_type == IBV_EVENT_PORT_ERR) &&
-			dev->data->dev_conf.intr_conf.lsc) {
-			mlx5_glue->ack_async_event(&event);
-			if (mlx5_link_update(dev, 0) == -EAGAIN) {
-				usleep(0);
-				continue;
-			}
-			_rte_eth_dev_callback_process
-				(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
-			continue;
-		}
 		DRV_LOG(DEBUG,
 			"port %u cannot handle an unknown event (type %d)",
 			dev->data->port_id, event.event_type);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 04b06e11d7..e91970ddae 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -331,11 +331,18 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 		priv->sh->port[priv->ibv_port - 1].ih_port_id =
 					(uint32_t)dev->data->port_id;
 	} else {
-		DRV_LOG(INFO, "port %u starts without LSC and RMV interrupts.",
+		DRV_LOG(INFO, "port %u starts without RMV interrupts.",
 			dev->data->port_id);
-		dev->data->dev_conf.intr_conf.lsc = 0;
 		dev->data->dev_conf.intr_conf.rmv = 0;
 	}
+	if (priv->sh->intr_handle_nl.fd >= 0) {
+		priv->sh->port[priv->ibv_port - 1].nl_ih_port_id =
+					(uint32_t)dev->data->port_id;
+	} else {
+		DRV_LOG(INFO, "port %u starts without LSC interrupts.",
+			dev->data->port_id);
+		dev->data->dev_conf.intr_conf.lsc = 0;
+	}
 	if (priv->sh->intr_handle_devx.fd >= 0)
 		priv->sh->port[priv->ibv_port - 1].devx_ih_port_id =
 					(uint32_t)dev->data->port_id;
@@ -379,6 +386,7 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
 	mlx5_rx_intr_vec_disable(dev);
 	priv->sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS;
 	priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS;
+	priv->sh->port[priv->ibv_port - 1].nl_ih_port_id = RTE_MAX_ETHPORTS;
 	mlx5_txq_stop(dev);
 	mlx5_rxq_stop(dev);
 }
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 19.11 3/3] net/mlx5: fix initial link status detection
  2022-03-11  8:06 [PATCH 19.11 0/3] net/mlx5: fix link state detection Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 1/3] common/mlx5: add Netlink event helpers Dmitry Kozlyuk
  2022-03-11  8:06 ` [PATCH 19.11 2/3] net/mlx5: fix link status change detection Dmitry Kozlyuk
@ 2022-03-11  8:06 ` Dmitry Kozlyuk
  2022-03-11 10:06 ` [PATCH 19.11 0/3] net/mlx5: fix link state detection Christian Ehrhardt
  3 siblings, 0 replies; 5+ messages in thread
From: Dmitry Kozlyuk @ 2022-03-11  8:06 UTC (permalink / raw)
  To: stable; +Cc: Christian Ehrhardt, Viacheslav Ovsiienko

[ upstream commit 655c3c26c11e7a6f1b5421afe40b06d580b8f2dd ]

Link status change takes time that depends on the HW and the kernel.
It was checked immediately after the change was issued at probing.
If the port had beed down before probing, a "down" state may be read,
while the port would be "up" imminently.
After that, DPDK reported the port as "down" mistakenly
and "ifconfig $DEV up" did not trigger an LSC event,
because from the system's perspective the port was "up" already.

Install Netlink event handler at port probe before requesting the port
to come up in order to receive LSC event even if it comes up
between probe and start.

Fixes: b6499434b83e ("net/mlx5: fix link status initialization")

Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Reviewed-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 068b0ef981..12c87175b9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2822,13 +2822,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Bring Ethernet device up. */
 	DRV_LOG(DEBUG, "port %u forcing Ethernet interface up",
 		eth_dev->data->port_id);
-	mlx5_set_link_up(eth_dev);
-	/*
-	 * Even though the interrupt handler is not installed yet,
-	 * interrupts will still trigger on the async_fd from
-	 * Verbs context returned by ibv_open_device().
-	 */
+	/* Read link status in case it is up and there will be no event. */
 	mlx5_link_update(eth_dev, 0);
+	/* Watch LSC interrupts between port probe and port start. */
+	priv->sh->port[priv->ibv_port - 1].nl_ih_port_id =
+							eth_dev->data->port_id;
+	mlx5_set_link_up(eth_dev);
 #ifdef HAVE_MLX5DV_DR_ESWITCH
 	if (!(config.hca_attr.eswitch_manager && config.dv_flow_en &&
 	      (switch_info->representor || switch_info->master)))
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 19.11 0/3] net/mlx5: fix link state detection
  2022-03-11  8:06 [PATCH 19.11 0/3] net/mlx5: fix link state detection Dmitry Kozlyuk
                   ` (2 preceding siblings ...)
  2022-03-11  8:06 ` [PATCH 19.11 3/3] net/mlx5: fix initial link status detection Dmitry Kozlyuk
@ 2022-03-11 10:06 ` Christian Ehrhardt
  3 siblings, 0 replies; 5+ messages in thread
From: Christian Ehrhardt @ 2022-03-11 10:06 UTC (permalink / raw)
  To: Dmitry Kozlyuk; +Cc: stable

On Fri, Mar 11, 2022 at 9:06 AM Dmitry Kozlyuk <dkozlyuk@nvidia.com> wrote:
>
> [ backport of https://inbox.dpdk.org/dev/20220301121514.41497-1-dkozlyuk@nvidia.com ]
>
> This patchset fixes two related issues:
> * In rare occasions with any HW link state change to UP was missed.
> * If a port was DOWN before startup, its netdev would come UP,
>   but appear DOWN in DPDK (especially probable with ConnectX-4).
>
> Dmitry Kozlyuk (3):
>   common/mlx5: add Netlink event helpers
>   net/mlx5: fix link status change detection
>   net/mlx5: fix initial link status detection

All three applied, thank you


>  drivers/net/mlx5/mlx5.c         |  59 +++++++++++++++---
>  drivers/net/mlx5/mlx5.h         |  10 ++-
>  drivers/net/mlx5/mlx5_ethdev.c  |  63 +++++++++++++++----
>  drivers/net/mlx5/mlx5_nl.c      | 107 +++++++++++++++++++++++++++++++-
>  drivers/net/mlx5/mlx5_trigger.c |  12 +++-
>  5 files changed, 224 insertions(+), 27 deletions(-)
>
> --
> 2.25.1
>


--
Christian Ehrhardt
Staff Engineer, Ubuntu Server
Canonical Ltd

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-03-11 10:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-11  8:06 [PATCH 19.11 0/3] net/mlx5: fix link state detection Dmitry Kozlyuk
2022-03-11  8:06 ` [PATCH 19.11 1/3] common/mlx5: add Netlink event helpers Dmitry Kozlyuk
2022-03-11  8:06 ` [PATCH 19.11 2/3] net/mlx5: fix link status change detection Dmitry Kozlyuk
2022-03-11  8:06 ` [PATCH 19.11 3/3] net/mlx5: fix initial link status detection Dmitry Kozlyuk
2022-03-11 10:06 ` [PATCH 19.11 0/3] net/mlx5: fix link state detection Christian Ehrhardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).