blob: 56e3ae64f3be71edacb83677795749b283bf012e [file] [log] [blame]
Joel Stanleyb314cb52017-06-07 14:51:57 +09301From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
Joel Stanley2b0f7b42016-07-19 23:26:28 +09302From: Carol L Soto <clsoto@linux.vnet.ibm.com>
3Date: Tue, 12 Jul 2016 17:04:07 -0500
Joel Stanleyb314cb52017-06-07 14:51:57 +09304Subject: [PATCH 05/11] net/mlx5: Add pci shutdown callback
Joel Stanley2b0f7b42016-07-19 23:26:28 +09305
6Backport of commit 5fc7197d3a256 ("net/mlx5: Add pci shutdown callback")
7so we can use for the OpenPower kernel.
8
9This patch introduces kexec support for mlx5.
10When switching kernels, kexec() calls shutdown, which unloads
11the driver and cleans its resources.
12
13In addition, remove unregister netdev from shutdown flow. This will
14allow a clean shutdown, even if some netdev clients did not release their
15reference from this netdev. Releasing The HW resources only is enough as
16the kernel is shutting down
17
18Signed-off-by: Majd Dibbiny <majd@mellanox.com>
19Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
20Signed-off-by: Haggai Abramovsky <hagaya@mellanox.com>
21Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
22Signed-off-by: David S. Miller <davem@davemloft.net>
23Signed-off-by: Carol L Soto <clsoto@linux.vnet.ibm.com>
24(cherry picked from commit 5fc7197d3a256d9c5de3134870304b24892a4908)
25Signed-off-by: Joel Stanley <joel@jms.id.au>
Samuel Mendoza-Jonas7d8f5b92017-10-17 14:16:45 +110026Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Joel Stanley2b0f7b42016-07-19 23:26:28 +093027---
28 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++++--
29 drivers/net/ethernet/mellanox/mlx5/core/main.c | 23 +++++++++++++++++++----
30 include/linux/mlx5/driver.h | 7 ++++---
31 3 files changed, 36 insertions(+), 9 deletions(-)
32
33diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Joel Stanley9e007f72016-09-15 20:05:01 +093034index 90e876ecc720..984668ec8a0b 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +093035--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
36+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
37@@ -2241,7 +2241,16 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
38 schedule_work(&priv->set_rx_mode_work);
39 mlx5e_disable_async_events(priv);
40 flush_scheduled_work();
41- unregister_netdev(netdev);
42+ if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
43+ netif_device_detach(netdev);
44+ mutex_lock(&priv->state_lock);
45+ if (test_bit(MLX5E_STATE_OPENED, &priv->state))
46+ mlx5e_close_locked(netdev);
47+ mutex_unlock(&priv->state_lock);
48+ } else {
49+ unregister_netdev(netdev);
50+ }
51+
52 mlx5e_destroy_flow_tables(priv);
53 mlx5e_destroy_tirs(priv);
54 mlx5e_destroy_rqt(priv, MLX5E_SINGLE_RQ_RQT);
55@@ -2252,7 +2261,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
56 mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
57 mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
58 mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
59- free_netdev(netdev);
60+
61+ if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state))
62+ free_netdev(netdev);
63 }
64
65 static void *mlx5e_get_netdev(void *vpriv)
66diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
Joel Stanley3f6d8432017-07-18 14:58:37 +093067index f5c1f4acc57b..aa39ff18b4f0 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +093068--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
69+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
Joel Stanley3f6d8432017-07-18 14:58:37 +093070@@ -921,7 +921,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
Joel Stanley2b0f7b42016-07-19 23:26:28 +093071 int err;
72
73 mutex_lock(&dev->intf_state_mutex);
74- if (dev->interface_state == MLX5_INTERFACE_STATE_UP) {
75+ if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
76 dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n",
77 __func__);
78 goto out;
Joel Stanley3f6d8432017-07-18 14:58:37 +093079@@ -1079,7 +1079,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
Joel Stanley2b0f7b42016-07-19 23:26:28 +093080 if (err)
81 pr_info("failed request module on %s\n", MLX5_IB_MOD);
82
83- dev->interface_state = MLX5_INTERFACE_STATE_UP;
84+ clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
85+ set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
86 out:
87 mutex_unlock(&dev->intf_state_mutex);
88
Joel Stanley3f6d8432017-07-18 14:58:37 +093089@@ -1141,7 +1142,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
Joel Stanley2b0f7b42016-07-19 23:26:28 +093090 int err = 0;
91
92 mutex_lock(&dev->intf_state_mutex);
93- if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) {
94+ if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
95 dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
96 __func__);
97 goto out;
Joel Stanley3f6d8432017-07-18 14:58:37 +093098@@ -1171,7 +1172,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
Joel Stanley2b0f7b42016-07-19 23:26:28 +093099 mlx5_cmd_cleanup(dev);
100
101 out:
102- dev->interface_state = MLX5_INTERFACE_STATE_DOWN;
103+ clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
104+ set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
105 mutex_unlock(&dev->intf_state_mutex);
106 return err;
107 }
Joel Stanley3f6d8432017-07-18 14:58:37 +0930108@@ -1381,6 +1383,18 @@ static const struct pci_error_handlers mlx5_err_handler = {
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930109 .resume = mlx5_pci_resume
110 };
111
112+static void shutdown(struct pci_dev *pdev)
113+{
114+ struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
115+ struct mlx5_priv *priv = &dev->priv;
116+
117+ dev_info(&pdev->dev, "Shutdown was called\n");
118+ /* Notify mlx5 clients that the kernel is being shut down */
119+ set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
120+ mlx5_unload_one(dev, priv);
121+ mlx5_pci_disable_device(dev);
122+}
123+
124 static const struct pci_device_id mlx5_core_pci_table[] = {
125 { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */
126 { PCI_VDEVICE(MELLANOX, 0x1012) }, /* Connect-IB VF */
Joel Stanley3f6d8432017-07-18 14:58:37 +0930127@@ -1398,6 +1412,7 @@ static struct pci_driver mlx5_core_driver = {
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930128 .id_table = mlx5_core_pci_table,
129 .probe = init_one,
130 .remove = remove_one,
131+ .shutdown = shutdown,
132 .err_handler = &mlx5_err_handler
133 };
134
135diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
136index 412aa988c6ad..dc26d9942120 100644
137--- a/include/linux/mlx5/driver.h
138+++ b/include/linux/mlx5/driver.h
139@@ -493,8 +493,9 @@ enum mlx5_device_state {
140 };
141
142 enum mlx5_interface_state {
143- MLX5_INTERFACE_STATE_DOWN,
144- MLX5_INTERFACE_STATE_UP,
145+ MLX5_INTERFACE_STATE_DOWN = BIT(0),
146+ MLX5_INTERFACE_STATE_UP = BIT(1),
147+ MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2),
148 };
149
150 enum mlx5_pci_status {
151@@ -518,7 +519,7 @@ struct mlx5_core_dev {
152 enum mlx5_device_state state;
153 /* sync interface state */
154 struct mutex intf_state_mutex;
155- enum mlx5_interface_state interface_state;
156+ unsigned long intf_state;
157 void (*event) (struct mlx5_core_dev *dev,
158 enum mlx5_dev_event event,
159 unsigned long param);