Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fc7197d authored by Majd Dibbiny's avatar Majd Dibbiny Committed by David S. Miller
Browse files

net/mlx5: Add pci shutdown callback



This patch introduces kexec support for mlx5.
When switching kernels, kexec() calls shutdown, which unloads
the driver and cleans its resources.

In addition, remove unregister netdev from shutdown flow. This will
allow a clean shutdown, even if some netdev clients did not release their
reference from this netdev. Releasing The HW resources only is enough as
the kernel is shutting down

Signed-off-by: default avatarMajd Dibbiny <majd@mellanox.com>
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarHaggai Abramovsky <hagaya@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 78228cbd
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -2633,7 +2633,16 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
	schedule_work(&priv->set_rx_mode_work);
	mlx5e_disable_async_events(priv);
	flush_scheduled_work();
	if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
		netif_device_detach(netdev);
		mutex_lock(&priv->state_lock);
		if (test_bit(MLX5E_STATE_OPENED, &priv->state))
			mlx5e_close_locked(netdev);
		mutex_unlock(&priv->state_lock);
	} else {
		unregister_netdev(netdev);
	}

	mlx5e_tc_cleanup(priv);
	mlx5e_vxlan_cleanup(priv);
	mlx5e_destroy_flow_tables(priv);
@@ -2646,6 +2655,8 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
	mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn);
	mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
	mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);

	if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state))
		free_netdev(netdev);
}

+19 −4
Original line number Diff line number Diff line
@@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
	int err;

	mutex_lock(&dev->intf_state_mutex);
	if (dev->interface_state == MLX5_INTERFACE_STATE_UP) {
	if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
		dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n",
			 __func__);
		goto out;
@@ -1133,7 +1133,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
	if (err)
		pr_info("failed request module on %s\n", MLX5_IB_MOD);

	dev->interface_state = MLX5_INTERFACE_STATE_UP;
	clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
	set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
out:
	mutex_unlock(&dev->intf_state_mutex);

@@ -1207,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
	}

	mutex_lock(&dev->intf_state_mutex);
	if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) {
	if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
		dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
			 __func__);
		goto out;
@@ -1241,7 +1242,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
	mlx5_cmd_cleanup(dev);

out:
	dev->interface_state = MLX5_INTERFACE_STATE_DOWN;
	clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
	set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
	mutex_unlock(&dev->intf_state_mutex);
	return err;
}
@@ -1452,6 +1454,18 @@ static const struct pci_error_handlers mlx5_err_handler = {
	.resume		= mlx5_pci_resume
};

static void shutdown(struct pci_dev *pdev)
{
	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
	struct mlx5_priv *priv = &dev->priv;

	dev_info(&pdev->dev, "Shutdown was called\n");
	/* Notify mlx5 clients that the kernel is being shut down */
	set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
	mlx5_unload_one(dev, priv);
	mlx5_pci_disable_device(dev);
}

static const struct pci_device_id mlx5_core_pci_table[] = {
	{ PCI_VDEVICE(MELLANOX, 0x1011) },			/* Connect-IB */
	{ PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF},	/* Connect-IB VF */
@@ -1471,6 +1485,7 @@ static struct pci_driver mlx5_core_driver = {
	.id_table       = mlx5_core_pci_table,
	.probe          = init_one,
	.remove         = remove_one,
	.shutdown	= shutdown,
	.err_handler	= &mlx5_err_handler,
	.sriov_configure   = mlx5_core_sriov_configure,
};
+4 −3
Original line number Diff line number Diff line
@@ -519,8 +519,9 @@ enum mlx5_device_state {
};

enum mlx5_interface_state {
	MLX5_INTERFACE_STATE_DOWN,
	MLX5_INTERFACE_STATE_UP,
	MLX5_INTERFACE_STATE_DOWN = BIT(0),
	MLX5_INTERFACE_STATE_UP = BIT(1),
	MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2),
};

enum mlx5_pci_status {
@@ -544,7 +545,7 @@ struct mlx5_core_dev {
	enum mlx5_device_state	state;
	/* sync interface state */
	struct mutex		intf_state_mutex;
	enum mlx5_interface_state interface_state;
	unsigned long		intf_state;
	void			(*event) (struct mlx5_core_dev *dev,
					  enum mlx5_dev_event event,
					  unsigned long param);