Revert "net/mlx4_en: Avoid unregister_netdev at shutdown flow"
authorTariq Toukan <tariqt@mellanox.com>
Sun, 27 Nov 2016 17:20:51 +0000 (19:20 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Nov 2016 20:33:46 +0000 (15:33 -0500)
This reverts commit 9d76931180557270796f9631e2c79b9c7bb3c9fb.

Using unregister_netdev at shutdown flow prevents calling
the netdev's ndos or trying to access its freed resources.

This fixes crashes like the following:
 Call Trace:
  [<ffffffff81587a6e>] dev_get_phys_port_id+0x1e/0x30
  [<ffffffff815a36ce>] rtnl_fill_ifinfo+0x4be/0xff0
  [<ffffffff815a53f3>] rtmsg_ifinfo_build_skb+0x73/0xe0
  [<ffffffff815a5476>] rtmsg_ifinfo.part.27+0x16/0x50
  [<ffffffff815a54c8>] rtmsg_ifinfo+0x18/0x20
  [<ffffffff8158a6c6>] netdev_state_change+0x46/0x50
  [<ffffffff815a5e78>] linkwatch_do_dev+0x38/0x50
  [<ffffffff815a6165>] __linkwatch_run_queue+0xf5/0x170
  [<ffffffff815a6205>] linkwatch_event+0x25/0x30
  [<ffffffff81099a82>] process_one_work+0x152/0x400
  [<ffffffff8109a325>] worker_thread+0x125/0x4b0
  [<ffffffff8109a200>] ? rescuer_thread+0x350/0x350
  [<ffffffff8109fc6a>] kthread+0xca/0xe0
  [<ffffffff8109fba0>] ? kthread_park+0x60/0x60
  [<ffffffff816a1285>] ret_from_fork+0x25/0x30

Fixes: 9d7693118055 ("net/mlx4_en: Avoid unregister_netdev at shutdown flow")
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Reported-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reported-by: Steve Wise <swise@opengridcomputing.com>
Cc: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/main.c
include/linux/mlx4/device.h

index a60f635da78b7d1bf16f6c0f05d66c8be824a7dc..fb8bb027b69c3332ef23d4b59f9288103a5b12ba 100644 (file)
@@ -2079,13 +2079,6 @@ err:
        return -ENOMEM;
 }
 
-static void mlx4_en_shutdown(struct net_device *dev)
-{
-       rtnl_lock();
-       netif_device_detach(dev);
-       mlx4_en_close(dev);
-       rtnl_unlock();
-}
 
 static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
                             struct mlx4_en_priv *src,
@@ -2162,8 +2155,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
-       bool shutdown = mdev->dev->persist->interface_state &
-                                           MLX4_INTERFACE_STATE_SHUTDOWN;
 
        en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 
@@ -2171,10 +2162,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        if (priv->registered) {
                devlink_port_type_clear(mlx4_get_devlink_port(mdev->dev,
                                                              priv->port));
-               if (shutdown)
-                       mlx4_en_shutdown(dev);
-               else
-                       unregister_netdev(dev);
+               unregister_netdev(dev);
        }
 
        if (priv->allocated)
@@ -2203,8 +2191,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        kfree(priv->tx_ring);
        kfree(priv->tx_cq);
 
-       if (!shutdown)
-               free_netdev(dev);
+       free_netdev(dev);
 }
 
 static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
index 6f4e67bc35382e7a0b8de7c0b52cc24b3d81df91..75d07fa9d0b1bb50f595adf9f65cf4dd9b8e4683 100644 (file)
@@ -4147,11 +4147,8 @@ static void mlx4_shutdown(struct pci_dev *pdev)
 
        mlx4_info(persist->dev, "mlx4_shutdown was called\n");
        mutex_lock(&persist->interface_state_mutex);
-       if (persist->interface_state & MLX4_INTERFACE_STATE_UP) {
-               /* Notify mlx4 clients that the kernel is being shut down */
-               persist->interface_state |= MLX4_INTERFACE_STATE_SHUTDOWN;
+       if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
                mlx4_unload_one(pdev);
-       }
        mutex_unlock(&persist->interface_state_mutex);
 }
 
index 3be7abd6e722d0c0f6a34f40a21327b81251f72e..c9f379689dd068beadbdb828fe8f09b521b28f12 100644 (file)
@@ -476,7 +476,6 @@ enum {
 enum {
        MLX4_INTERFACE_STATE_UP         = 1 << 0,
        MLX4_INTERFACE_STATE_DELETION   = 1 << 1,
-       MLX4_INTERFACE_STATE_SHUTDOWN   = 1 << 2,
 };
 
 #define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \