blob: 770b0597b2e602fdf6e0ea18cd2b2e1dcc1c6376 [file] [log] [blame]
Joel Stanley4529c8c2016-10-25 13:59:27 +10301From f00bd9648a50f06e77c04a36c4506e36ea0a27e0 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 Stanleyeeef14f2016-08-16 23:09:53 +09304Subject: [PATCH 5/9] 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>
26---
27 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++++--
28 drivers/net/ethernet/mellanox/mlx5/core/main.c | 23 +++++++++++++++++++----
29 include/linux/mlx5/driver.h | 7 ++++---
30 3 files changed, 36 insertions(+), 9 deletions(-)
31
32diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Joel Stanley7291da52016-09-15 20:05:01 +093033index 90e876ecc720..984668ec8a0b 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +093034--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
35+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
36@@ -2241,7 +2241,16 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
37 schedule_work(&priv->set_rx_mode_work);
38 mlx5e_disable_async_events(priv);
39 flush_scheduled_work();
40- unregister_netdev(netdev);
41+ if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
42+ netif_device_detach(netdev);
43+ mutex_lock(&priv->state_lock);
44+ if (test_bit(MLX5E_STATE_OPENED, &priv->state))
45+ mlx5e_close_locked(netdev);
46+ mutex_unlock(&priv->state_lock);
47+ } else {
48+ unregister_netdev(netdev);
49+ }
50+
51 mlx5e_destroy_flow_tables(priv);
52 mlx5e_destroy_tirs(priv);
53 mlx5e_destroy_rqt(priv, MLX5E_SINGLE_RQ_RQT);
54@@ -2252,7 +2261,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
55 mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
56 mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
57 mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
58- free_netdev(netdev);
59+
60+ if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state))
61+ free_netdev(netdev);
62 }
63
64 static void *mlx5e_get_netdev(void *vpriv)
65diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
66index 6cf6d93d8831..8a371bdb823e 100644
67--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
68+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
69@@ -914,7 +914,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
70 int err;
71
72 mutex_lock(&dev->intf_state_mutex);
73- if (dev->interface_state == MLX5_INTERFACE_STATE_UP) {
74+ if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
75 dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n",
76 __func__);
77 goto out;
78@@ -1063,7 +1063,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
79 if (err)
80 pr_info("failed request module on %s\n", MLX5_IB_MOD);
81
82- dev->interface_state = MLX5_INTERFACE_STATE_UP;
83+ clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
84+ set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
85 out:
86 mutex_unlock(&dev->intf_state_mutex);
87
88@@ -1125,7 +1126,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
89 int err = 0;
90
91 mutex_lock(&dev->intf_state_mutex);
92- if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) {
93+ if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
94 dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
95 __func__);
96 goto out;
97@@ -1155,7 +1156,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
98 mlx5_cmd_cleanup(dev);
99
100 out:
101- dev->interface_state = MLX5_INTERFACE_STATE_DOWN;
102+ clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
103+ set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
104 mutex_unlock(&dev->intf_state_mutex);
105 return err;
106 }
107@@ -1365,6 +1367,18 @@ static const struct pci_error_handlers mlx5_err_handler = {
108 .resume = mlx5_pci_resume
109 };
110
111+static void shutdown(struct pci_dev *pdev)
112+{
113+ struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
114+ struct mlx5_priv *priv = &dev->priv;
115+
116+ dev_info(&pdev->dev, "Shutdown was called\n");
117+ /* Notify mlx5 clients that the kernel is being shut down */
118+ set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
119+ mlx5_unload_one(dev, priv);
120+ mlx5_pci_disable_device(dev);
121+}
122+
123 static const struct pci_device_id mlx5_core_pci_table[] = {
124 { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */
125 { PCI_VDEVICE(MELLANOX, 0x1012) }, /* Connect-IB VF */
126@@ -1382,6 +1396,7 @@ static struct pci_driver mlx5_core_driver = {
127 .id_table = mlx5_core_pci_table,
128 .probe = init_one,
129 .remove = remove_one,
130+ .shutdown = shutdown,
131 .err_handler = &mlx5_err_handler
132 };
133
134diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
135index 412aa988c6ad..dc26d9942120 100644
136--- a/include/linux/mlx5/driver.h
137+++ b/include/linux/mlx5/driver.h
138@@ -493,8 +493,9 @@ enum mlx5_device_state {
139 };
140
141 enum mlx5_interface_state {
142- MLX5_INTERFACE_STATE_DOWN,
143- MLX5_INTERFACE_STATE_UP,
144+ MLX5_INTERFACE_STATE_DOWN = BIT(0),
145+ MLX5_INTERFACE_STATE_UP = BIT(1),
146+ MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2),
147 };
148
149 enum mlx5_pci_status {
150@@ -518,7 +519,7 @@ struct mlx5_core_dev {
151 enum mlx5_device_state state;
152 /* sync interface state */
153 struct mutex intf_state_mutex;
154- enum mlx5_interface_state interface_state;
155+ unsigned long intf_state;
156 void (*event) (struct mlx5_core_dev *dev,
157 enum mlx5_dev_event event,
158 unsigned long param);
159--
Joel Stanley8f1d88e2016-08-29 16:44:12 +09301602.9.3
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930161