]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.4.95/net-mlx4_core-preserve-pci_dev_data-after-__mlx4_remove_one.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.4.95 / net-mlx4_core-preserve-pci_dev_data-after-__mlx4_remove_one.patch
1 From foo@baz Wed Jun 18 20:03:44 PDT 2014
2 From: Wei Yang <weiyang@linux.vnet.ibm.com>
3 Date: Sun, 1 Jun 2014 15:25:20 +0800
4 Subject: net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()
5
6 From: Wei Yang <weiyang@linux.vnet.ibm.com>
7
8 [ Upstream commit befdf8978accecac2e0739e6b5075afc62db37fe ]
9
10 This patch wrap up a helper function __mlx4_remove_one() which does the tear
11 down function but preserve the drv_data. Functions like
12 mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out
13 releasing drvdata.
14
15 Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
16 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
17 ---
18 drivers/net/ethernet/mellanox/mlx4/main.c | 145 ++++++++++++++++--------------
19 drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1
20 2 files changed, 83 insertions(+), 63 deletions(-)
21
22 --- a/drivers/net/ethernet/mellanox/mlx4/main.c
23 +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
24 @@ -1798,15 +1798,8 @@ static int __mlx4_init_one(struct pci_de
25 /* Allow large DMA segments, up to the firmware limit of 1 GB */
26 dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
27
28 - priv = kzalloc(sizeof *priv, GFP_KERNEL);
29 - if (!priv) {
30 - dev_err(&pdev->dev, "Device struct alloc failed, "
31 - "aborting.\n");
32 - err = -ENOMEM;
33 - goto err_release_regions;
34 - }
35 -
36 - dev = &priv->dev;
37 + dev = pci_get_drvdata(pdev);
38 + priv = mlx4_priv(dev);
39 dev->pdev = pdev;
40 INIT_LIST_HEAD(&priv->ctx_list);
41 spin_lock_init(&priv->ctx_lock);
42 @@ -1967,8 +1960,7 @@ slave_start:
43 mlx4_sense_init(dev);
44 mlx4_start_sense(dev);
45
46 - priv->pci_dev_data = pci_dev_data;
47 - pci_set_drvdata(pdev, dev);
48 + priv->removed = 0;
49
50 return 0;
51
52 @@ -2035,73 +2027,100 @@ err_disable_pdev:
53 static int __devinit mlx4_init_one(struct pci_dev *pdev,
54 const struct pci_device_id *id)
55 {
56 + struct mlx4_priv *priv;
57 + struct mlx4_dev *dev;
58 +
59 printk_once(KERN_INFO "%s", mlx4_version);
60
61 + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
62 + if (!priv)
63 + return -ENOMEM;
64 +
65 + dev = &priv->dev;
66 + pci_set_drvdata(pdev, dev);
67 + priv->pci_dev_data = id->driver_data;
68 +
69 return __mlx4_init_one(pdev, id->driver_data);
70 }
71
72 -static void mlx4_remove_one(struct pci_dev *pdev)
73 +static void __mlx4_remove_one(struct pci_dev *pdev)
74 {
75 struct mlx4_dev *dev = pci_get_drvdata(pdev);
76 struct mlx4_priv *priv = mlx4_priv(dev);
77 + int pci_dev_data;
78 int p;
79
80 - if (dev) {
81 - /* in SRIOV it is not allowed to unload the pf's
82 - * driver while there are alive vf's */
83 - if (mlx4_is_master(dev)) {
84 - if (mlx4_how_many_lives_vf(dev))
85 - printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
86 - }
87 - mlx4_stop_sense(dev);
88 - mlx4_unregister_device(dev);
89 + if (priv->removed)
90 + return;
91
92 - for (p = 1; p <= dev->caps.num_ports; p++) {
93 - mlx4_cleanup_port_info(&priv->port[p]);
94 - mlx4_CLOSE_PORT(dev, p);
95 - }
96 + pci_dev_data = priv->pci_dev_data;
97
98 - mlx4_cleanup_counters_table(dev);
99 - mlx4_cleanup_mcg_table(dev);
100 - mlx4_cleanup_qp_table(dev);
101 - mlx4_cleanup_srq_table(dev);
102 - mlx4_cleanup_cq_table(dev);
103 - mlx4_cmd_use_polling(dev);
104 - mlx4_cleanup_eq_table(dev);
105 - mlx4_cleanup_mr_table(dev);
106 - mlx4_cleanup_xrcd_table(dev);
107 - mlx4_cleanup_pd_table(dev);
108 + /* in SRIOV it is not allowed to unload the pf's
109 + * driver while there are alive vf's */
110 + if (mlx4_is_master(dev)) {
111 + if (mlx4_how_many_lives_vf(dev))
112 + printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
113 + }
114 + mlx4_stop_sense(dev);
115 + mlx4_unregister_device(dev);
116
117 - if (mlx4_is_master(dev))
118 - mlx4_free_resource_tracker(dev);
119 + for (p = 1; p <= dev->caps.num_ports; p++) {
120 + mlx4_cleanup_port_info(&priv->port[p]);
121 + mlx4_CLOSE_PORT(dev, p);
122 + }
123
124 - iounmap(priv->kar);
125 - mlx4_uar_free(dev, &priv->driver_uar);
126 - mlx4_cleanup_uar_table(dev);
127 - if (!mlx4_is_slave(dev))
128 - mlx4_clear_steering(dev);
129 - mlx4_free_eq_table(dev);
130 - if (mlx4_is_master(dev))
131 - mlx4_multi_func_cleanup(dev);
132 - mlx4_close_hca(dev);
133 - if (mlx4_is_slave(dev))
134 - mlx4_multi_func_cleanup(dev);
135 - mlx4_cmd_cleanup(dev);
136 -
137 - if (dev->flags & MLX4_FLAG_MSI_X)
138 - pci_disable_msix(pdev);
139 - if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
140 - mlx4_warn(dev, "Disabling sriov\n");
141 - pci_disable_sriov(pdev);
142 - }
143 + mlx4_cleanup_counters_table(dev);
144 + mlx4_cleanup_mcg_table(dev);
145 + mlx4_cleanup_qp_table(dev);
146 + mlx4_cleanup_srq_table(dev);
147 + mlx4_cleanup_cq_table(dev);
148 + mlx4_cmd_use_polling(dev);
149 + mlx4_cleanup_eq_table(dev);
150 + mlx4_cleanup_mr_table(dev);
151 + mlx4_cleanup_xrcd_table(dev);
152 + mlx4_cleanup_pd_table(dev);
153 +
154 + if (mlx4_is_master(dev))
155 + mlx4_free_resource_tracker(dev);
156 +
157 + iounmap(priv->kar);
158 + mlx4_uar_free(dev, &priv->driver_uar);
159 + mlx4_cleanup_uar_table(dev);
160 + if (!mlx4_is_slave(dev))
161 + mlx4_clear_steering(dev);
162 + mlx4_free_eq_table(dev);
163 + if (mlx4_is_master(dev))
164 + mlx4_multi_func_cleanup(dev);
165 + mlx4_close_hca(dev);
166 + if (mlx4_is_slave(dev))
167 + mlx4_multi_func_cleanup(dev);
168 + mlx4_cmd_cleanup(dev);
169
170 - if (!mlx4_is_slave(dev))
171 - mlx4_free_ownership(dev);
172 - kfree(priv);
173 - pci_release_regions(pdev);
174 - pci_disable_device(pdev);
175 - pci_set_drvdata(pdev, NULL);
176 + if (dev->flags & MLX4_FLAG_MSI_X)
177 + pci_disable_msix(pdev);
178 + if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
179 + mlx4_warn(dev, "Disabling sriov\n");
180 + pci_disable_sriov(pdev);
181 }
182 +
183 + if (!mlx4_is_slave(dev))
184 + mlx4_free_ownership(dev);
185 +
186 + pci_release_regions(pdev);
187 + pci_disable_device(pdev);
188 + memset(priv, 0, sizeof(*priv));
189 + priv->pci_dev_data = pci_dev_data;
190 + priv->removed = 1;
191 +}
192 +
193 +static void mlx4_remove_one(struct pci_dev *pdev)
194 +{
195 + struct mlx4_dev *dev = pci_get_drvdata(pdev);
196 + struct mlx4_priv *priv = mlx4_priv(dev);
197 +
198 + __mlx4_remove_one(pdev);
199 + kfree(priv);
200 + pci_set_drvdata(pdev, NULL);
201 }
202
203 int mlx4_restart_one(struct pci_dev *pdev)
204 @@ -2111,7 +2130,7 @@ int mlx4_restart_one(struct pci_dev *pde
205 int pci_dev_data;
206
207 pci_dev_data = priv->pci_dev_data;
208 - mlx4_remove_one(pdev);
209 + __mlx4_remove_one(pdev);
210 return __mlx4_init_one(pdev, pci_dev_data);
211 }
212
213 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
214 +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
215 @@ -723,6 +723,7 @@ struct mlx4_priv {
216 spinlock_t ctx_lock;
217
218 int pci_dev_data;
219 + int removed;
220
221 struct list_head pgdir_list;
222 struct mutex pgdir_mutex;