]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net/mlx4_en: Avoid scheduling restart task if it is already running
authorMoshe Shemesh <moshe@mellanox.com>
Wed, 9 Dec 2020 13:03:38 +0000 (15:03 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Dec 2020 10:25:41 +0000 (11:25 +0100)
[ Upstream commit fed91613c9dd455dd154b22fa8e11b8526466082 ]

Add restarting state flag to avoid scheduling another restart task while
such task is already running. Change task name from watchdog_task to
restart_task to better fit the task role.

Fixes: 1e338db56e5a ("mlx4_en: Fix a race at restart task")
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

index 5868ec11db1af907547bd9dbc1f3f229cea650f6..a3a1947486e06b6008a8d9f08c98361f2f5ede5d 100644 (file)
@@ -1384,8 +1384,10 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
        }
 
        priv->port_stats.tx_timeout++;
-       en_dbg(DRV, priv, "Scheduling watchdog\n");
-       queue_work(mdev->workqueue, &priv->watchdog_task);
+       if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state)) {
+               en_dbg(DRV, priv, "Scheduling port restart\n");
+               queue_work(mdev->workqueue, &priv->restart_task);
+       }
 }
 
 
@@ -1835,6 +1837,7 @@ int mlx4_en_start_port(struct net_device *dev)
                local_bh_enable();
        }
 
+       clear_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state);
        netif_tx_start_all_queues(dev);
        netif_device_attach(dev);
 
@@ -2005,7 +2008,7 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
 static void mlx4_en_restart(struct work_struct *work)
 {
        struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
-                                                watchdog_task);
+                                                restart_task);
        struct mlx4_en_dev *mdev = priv->mdev;
        struct net_device *dev = priv->dev;
 
@@ -2387,7 +2390,7 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
        if (netif_running(dev)) {
                mutex_lock(&mdev->state_lock);
                if (!mdev->device_up) {
-                       /* NIC is probably restarting - let watchdog task reset
+                       /* NIC is probably restarting - let restart task reset
                         * the port */
                        en_dbg(DRV, priv, "Change MTU called with card down!?\n");
                } else {
@@ -2396,7 +2399,9 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
                        if (err) {
                                en_err(priv, "Failed restarting port:%d\n",
                                         priv->port);
-                               queue_work(mdev->workqueue, &priv->watchdog_task);
+                               if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING,
+                                                     &priv->state))
+                                       queue_work(mdev->workqueue, &priv->restart_task);
                        }
                }
                mutex_unlock(&mdev->state_lock);
@@ -2882,7 +2887,8 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
                if (err) {
                        en_err(priv, "Failed starting port %d for XDP change\n",
                               priv->port);
-                       queue_work(mdev->workqueue, &priv->watchdog_task);
+                       if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state))
+                               queue_work(mdev->workqueue, &priv->restart_task);
                }
        }
 
@@ -3280,7 +3286,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
        spin_lock_init(&priv->stats_lock);
        INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
-       INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
+       INIT_WORK(&priv->restart_task, mlx4_en_restart);
        INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
        INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
        INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task);
index 240f9c9ca943d2d2d6c10835e9d653ce1b8f288e..3cce101e83eefbb9d47bef1cfa2badc67cb6a365 100644 (file)
@@ -530,6 +530,10 @@ struct mlx4_en_stats_bitmap {
        struct mutex mutex; /* for mutual access to stats bitmap */
 };
 
+enum {
+       MLX4_EN_STATE_FLAG_RESTARTING,
+};
+
 struct mlx4_en_priv {
        struct mlx4_en_dev *mdev;
        struct mlx4_en_port_profile *prof;
@@ -595,7 +599,7 @@ struct mlx4_en_priv {
        struct mlx4_en_cq *rx_cq[MAX_RX_RINGS];
        struct mlx4_qp drop_qp;
        struct work_struct rx_mode_task;
-       struct work_struct watchdog_task;
+       struct work_struct restart_task;
        struct work_struct linkstate_task;
        struct delayed_work stats_task;
        struct delayed_work service_task;
@@ -643,6 +647,7 @@ struct mlx4_en_priv {
        u32 pflags;
        u8 rss_key[MLX4_EN_RSS_KEY_SIZE];
        u8 rss_hash_fn;
+       unsigned long state;
 };
 
 enum mlx4_en_wol {