]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx5: fix link state on device start
authorShahaf Shuler <shahafs@mellanox.com>
Thu, 25 Jan 2018 16:04:28 +0000 (18:04 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 29 Jan 2018 09:04:28 +0000 (10:04 +0100)
Following commit c7bf62255edf ("net/mlx5: fix handling link status event")
the link state must be up in order for the burst function to be set on
the device ops.

As the link may take time to move between down and up state it is
possible the rte_eth_dev_start call will return with wrong burst
function (either null or the empty burst function).

Fixing it by forcing the link to be up before returning from device
start. In case the link is still not up after 5 seconds fail the function.
In addition initialize the burst function on device probe to prevent
crashes before the link is up.

Fixes: c7bf62255edf ("net/mlx5: fix handling link status event")
Cc: stable@dpdk.org
Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_defs.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_trigger.c

index 445729c548bc6fa14fb9feaadf349ff37e5fffde..8a549edd7e40f0ea580d3b74fbf7836383e3bb2b 100644 (file)
@@ -858,6 +858,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                eth_dev->device = &pci_dev->device;
                rte_eth_copy_pci_info(eth_dev, pci_dev);
                eth_dev->device->driver = &mlx5_driver.driver;
+               /*
+                * Initialize burst functions to prevent crashes before link-up.
+                */
+               eth_dev->rx_pkt_burst = removed_rx_burst;
+               eth_dev->tx_pkt_burst = removed_tx_burst;
                priv->dev = eth_dev;
                eth_dev->dev_ops = &mlx5_dev_ops;
                /* Register MAC address. */
index 2602267c38c6e3f47b9c9e09223e1546c2f3ff25..f9e18c2944072dc50354afc3f69d33a1649b0722 100644 (file)
@@ -245,6 +245,7 @@ int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
 const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 int priv_link_update(struct priv *, int);
+int priv_force_link_status_change(struct priv *, int);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
index a71db281da28fd06f563397efd3efdf03ad9efa5..57f295c586d97b12ad0d5754c56d1314972e388e 100644 (file)
 /* Supported RSS */
 #define MLX5_RSS_HF_MASK (~(ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP))
 
+/* Maximum number of attempts to query link status before giving up. */
+#define MLX5_MAX_LINK_QUERY_ATTEMPTS 5
+
 #endif /* RTE_PMD_MLX5_DEFS_H_ */
index c886aefeaad576ee75174a463d312d3f55dc2a08..83657f5092a619025a2e9cd8f5f617bfe498d627 100644 (file)
@@ -966,6 +966,33 @@ priv_link_update(struct priv *priv, int wait_to_complete)
        return ret;
 }
 
+/**
+ * Querying the link status till it changes to the desired state.
+ * Number of query attempts is bounded by MLX5_MAX_LINK_QUERY_ATTEMPTS.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ * @param status
+ *   Link desired status.
+ *
+ * @return
+ *   0 on success, negative errno value on failure.
+ */
+int
+priv_force_link_status_change(struct priv *priv, int status)
+{
+       int try = 0;
+
+       while (try < MLX5_MAX_LINK_QUERY_ATTEMPTS) {
+               priv_link_update(priv, 0);
+               if (priv->dev->data->dev_link.link_status == status)
+                       return 0;
+               try++;
+               sleep(1);
+       }
+       return -EAGAIN;
+}
+
 /**
  * DPDK callback to retrieve physical link information.
  *
index 827db2e7e86bae4bed58a94bd0a5835a5527534d..c5429e182effaac2b976c87d4b251a3f5394c59a 100644 (file)
@@ -166,7 +166,13 @@ mlx5_dev_start(struct rte_eth_dev *dev)
        priv_xstats_init(priv);
        /* Update link status and Tx/Rx callbacks for the first time. */
        memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
-       priv_link_update(priv, 1);
+       INFO("Forcing port %u link to be up", dev->data->port_id);
+       err = priv_force_link_status_change(priv, ETH_LINK_UP);
+       if (err) {
+               DEBUG("Failed to set port %u link to be up",
+                     dev->data->port_id);
+               goto error;
+       }
        priv_dev_interrupt_handler_install(priv, dev);
        priv_unlock(priv);
        return 0;