]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx4: fix removal detection of stopped port
authorMoti Haimovsky <motih@mellanox.com>
Mon, 29 Jan 2018 08:34:37 +0000 (10:34 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 30 Jan 2018 09:20:35 +0000 (10:20 +0100)
In failsafe device start can be called for ports/devices that
had been plugged out.
The mlx4 PMD detects device removal by listening to the device RMV
events, when the mlx4 port is being stopped, the PMD no longer
listens to these events causing the PMD to stop detecting device
removals.
This patch fixes this issue by moving installation of the interrupt
handler to device configuration, and toggle only the Rx-queue
interrupts on start/stop.

Fixes: a6e8b01c3c26 ("net/mlx4: compact interrupt functions")
Cc: stable@dpdk.org
Signed-off-by: Moti Haimovsky <motih@mellanox.com>
Acked-by: Shahaf Shuler <shahafs@mellanox.com>
drivers/net/mlx4/mlx4.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/mlx4_intr.c

index 952dae08a3a64d25fac7a4437b2b2b221517faae..680eca7bccb7612a617a214fa6dbfb7a828e13b2 100644 (file)
@@ -108,7 +108,13 @@ mlx4_dev_configure(struct rte_eth_dev *dev)
                      " flow error type %d, cause %p, message: %s",
                      -ret, strerror(-ret), error.type, error.cause,
                      error.message ? error.message : "(unspecified)");
+               goto exit;
        }
+       ret = mlx4_intr_install(priv);
+       if (ret)
+               ERROR("%p: interrupt handler installation failed",
+                     (void *)dev);
+exit:
        return ret;
 }
 
@@ -141,7 +147,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
                      (void *)dev, strerror(-ret));
                goto err;
        }
-       ret = mlx4_intr_install(priv);
+       ret = mlx4_rxq_intr_enable(priv);
        if (ret) {
                ERROR("%p: interrupt handler installation failed",
                     (void *)dev);
@@ -187,7 +193,7 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
        dev->rx_pkt_burst = mlx4_rx_burst_removed;
        rte_wmb();
        mlx4_flow_sync(priv, NULL);
-       mlx4_intr_uninstall(priv);
+       mlx4_rxq_intr_disable(priv);
        mlx4_rss_deinit(priv);
 }
 
index 30a544f9aeebb08f6e23007f48d1b308a6e08dac..d65879f5233866e6711b7388b0aa6a0d0077c4bf 100644 (file)
@@ -177,6 +177,8 @@ int mlx4_is_removed(struct rte_eth_dev *dev);
 
 int mlx4_intr_uninstall(struct priv *priv);
 int mlx4_intr_install(struct priv *priv);
+int mlx4_rxq_intr_enable(struct priv *priv);
+void mlx4_rxq_intr_disable(struct priv *priv);
 int mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);
 int mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);
 
index 2ff72188a78de3db1c3af79a2987a5a318f990d2..e52294957c8fa6d32dc5468ad2e1fe37bb22e92d 100644 (file)
@@ -291,7 +291,7 @@ mlx4_intr_uninstall(struct priv *priv)
        }
        rte_eal_alarm_cancel((void (*)(void *))mlx4_link_status_alarm, priv);
        priv->intr_alarm = 0;
-       mlx4_rx_intr_vec_disable(priv);
+       mlx4_rxq_intr_disable(priv);
        rte_errno = err;
        return 0;
 }
@@ -313,8 +313,6 @@ mlx4_intr_install(struct priv *priv)
        int rc;
 
        mlx4_intr_uninstall(priv);
-       if (intr_conf->rxq && mlx4_rx_intr_vec_enable(priv) < 0)
-               goto error;
        if (intr_conf->lsc | intr_conf->rmv) {
                priv->intr_handle.fd = priv->ctx->async_fd;
                rc = rte_intr_callback_register(&priv->intr_handle,
@@ -395,3 +393,40 @@ mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
        }
        return -ret;
 }
+
+/**
+ * Enable datapath interrupts.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_rxq_intr_enable(struct priv *priv)
+{
+       const struct rte_intr_conf *const intr_conf =
+               &priv->dev->data->dev_conf.intr_conf;
+
+       if (intr_conf->rxq && mlx4_rx_intr_vec_enable(priv) < 0)
+               goto error;
+       return 0;
+error:
+       return -rte_errno;
+}
+
+/**
+ * Disable datapath interrupts, keeping other interrupts intact.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ */
+void
+mlx4_rxq_intr_disable(struct priv *priv)
+{
+       int err = rte_errno; /* Make sure rte_errno remains unchanged. */
+
+       mlx4_rx_intr_vec_disable(priv);
+       rte_errno = err;
+}