DPDK patches and discussions
 help / color / mirror / Atom feed
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
To: Gaetan Rivet <gaetan.rivet@6wind.com>, Matan Azrad <matan@mellanox.com>
Cc: dev@dpdk.org, stable@dpdk.org
Subject: [dpdk-dev] [PATCH v1 2/3] net/mlx4: fix rescheduled link status check
Date: Tue,  5 Sep 2017 14:56:38 +0200	[thread overview]
Message-ID: <37eb55eea3810bebde392d934e7366efaeb0f0a8.1504614801.git.adrien.mazarguil@6wind.com> (raw)
In-Reply-To: <cover.1504614801.git.adrien.mazarguil@6wind.com>

Link status is sometimes inconsistent during a LSC event. When it occurs,
the PMD refrains from immediately notifying the application; instead, an
alarm is scheduled to check link status later and notify the application
once it has settled.

The problem is that subsequent link status checks are only performed if
additional LSC events occur in the meantime, which is not always the case.

Worse, since support for removal events was added, rescheduled link status
checks may consume them as well without notifying the application. With the
right timing, a link loss occurring just before a device removal event may
hide it from the application.

Fixes: 6dd7b7056d7f ("net/mlx4: support device removal event")
Fixes: 2d449f7c52de ("net/mlx4: fix assertion failure on link update")
Cc: stable@dpdk.org
Cc: Gaetan Rivet <gaetan.rivet@6wind.com>

Reported-by: Matan Azrad <matan@mellanox.com>
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx4/mlx4_intr.c | 71 +++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 25 deletions(-)

diff --git a/drivers/net/mlx4/mlx4_intr.c b/drivers/net/mlx4/mlx4_intr.c
index d7f1098..e1e6c05 100644
--- a/drivers/net/mlx4/mlx4_intr.c
+++ b/drivers/net/mlx4/mlx4_intr.c
@@ -59,7 +59,7 @@
 #include "mlx4_rxtx.h"
 #include "mlx4_utils.h"
 
-static void mlx4_link_status_alarm(struct priv *priv);
+static int mlx4_link_status_check(struct priv *priv);
 
 /**
  * Clean up Rx interrupts handler.
@@ -149,8 +149,6 @@ static int
 mlx4_collect_interrupt_events(struct priv *priv, uint32_t *events)
 {
 	struct ibv_async_event event;
-	int port_change = 0;
-	struct rte_eth_link *link = &priv->dev->data->dev_link;
 	const struct rte_intr_conf *const intr_conf =
 		&priv->dev->data->dev_conf.intr_conf;
 	int ret = 0;
@@ -163,9 +161,9 @@ mlx4_collect_interrupt_events(struct priv *priv, uint32_t *events)
 		switch (event.event_type) {
 		case IBV_EVENT_PORT_ACTIVE:
 		case IBV_EVENT_PORT_ERR:
-			if (!intr_conf->lsc)
+			if (!intr_conf->lsc || mlx4_link_status_check(priv))
 				break;
-			port_change = 1;
+			*events |= (1 << RTE_ETH_EVENT_INTR_LSC);
 			ret++;
 			break;
 		case IBV_EVENT_DEVICE_FATAL:
@@ -180,47 +178,70 @@ mlx4_collect_interrupt_events(struct priv *priv, uint32_t *events)
 		}
 		ibv_ack_async_event(&event);
 	}
-	if (!port_change)
-		return ret;
-	mlx4_link_update(priv->dev, 0);
-	if (((link->link_speed == 0) && link->link_status) ||
-	    ((link->link_speed != 0) && !link->link_status)) {
-		if (!priv->intr_alarm) {
-			/* Inconsistent status, check again later. */
-			priv->intr_alarm = 1;
-			rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
-					  (void (*)(void *))
-					  mlx4_link_status_alarm,
-					  priv);
-		}
-	} else {
-		*events |= (1 << RTE_ETH_EVENT_INTR_LSC);
-	}
 	return ret;
 }
 
 /**
  * Process scheduled link status check.
  *
+ * If LSC interrupts are requested, process related callback.
+ *
  * @param priv
  *   Pointer to private structure.
  */
 static void
 mlx4_link_status_alarm(struct priv *priv)
 {
-	uint32_t events;
-	int ret;
+	const struct rte_intr_conf *const intr_conf =
+		&priv->dev->data->dev_conf.intr_conf;
 
 	assert(priv->intr_alarm == 1);
 	priv->intr_alarm = 0;
-	ret = mlx4_collect_interrupt_events(priv, &events);
-	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
+	if (intr_conf->lsc && !mlx4_link_status_check(priv))
 		_rte_eth_dev_callback_process(priv->dev,
 					      RTE_ETH_EVENT_INTR_LSC,
 					      NULL, NULL);
 }
 
 /**
+ * Check link status.
+ *
+ * In case of inconsistency, another check is scheduled.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   0 on success (link status is consistent), negative errno value
+ *   otherwise and rte_errno is set.
+ */
+static int
+mlx4_link_status_check(struct priv *priv)
+{
+	struct rte_eth_link *link = &priv->dev->data->dev_link;
+	int ret = mlx4_link_update(priv->dev, 0);
+
+	if (ret)
+		return ret;
+	if ((!link->link_speed && link->link_status) ||
+	    (link->link_speed && !link->link_status)) {
+		if (!priv->intr_alarm) {
+			/* Inconsistent status, check again later. */
+			ret = rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
+						(void (*)(void *))
+						mlx4_link_status_alarm,
+						priv);
+			if (ret)
+				return ret;
+			priv->intr_alarm = 1;
+		}
+		rte_errno = EINPROGRESS;
+		return -rte_errno;
+	}
+	return 0;
+}
+
+/**
  * Handle interrupts from the NIC.
  *
  * @param priv
-- 
2.1.4

  parent reply	other threads:[~2017-09-05 12:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-05 12:56 [dpdk-dev] [PATCH v1 0/3] net/mlx4: additional interrupt handling fixes Adrien Mazarguil
2017-09-05 12:56 ` [dpdk-dev] [PATCH v1 1/3] net/mlx4: fix unhandled event debug message Adrien Mazarguil
2017-09-05 12:56 ` Adrien Mazarguil [this message]
2017-09-05 12:56 ` [dpdk-dev] [PATCH v1 3/3] net/mlx4: merge interrupt collector function Adrien Mazarguil
2017-09-05 13:29   ` Gaëtan Rivet
2017-09-05 13:28 ` [dpdk-dev] [PATCH v1 0/3] net/mlx4: additional interrupt handling fixes Gaëtan Rivet
2017-09-08  9:10 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=37eb55eea3810bebde392d934e7366efaeb0f0a8.1504614801.git.adrien.mazarguil@6wind.com \
    --to=adrien.mazarguil@6wind.com \
    --cc=dev@dpdk.org \
    --cc=gaetan.rivet@6wind.com \
    --cc=matan@mellanox.com \
    --cc=stable@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).