diff options
author | Doug Ledford <dledford@redhat.com> | 2014-12-10 11:47:02 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-12-15 21:11:15 -0500 |
commit | 3bcce487fda8161597c20ed303d510e41ad7770e (patch) | |
tree | 0f36ea1c32ea745e2efd51d36940f382ab28bd5e | |
parent | e5d1dcf1b0951f4ba00d93653942dda6196109d8 (diff) |
IPoIB: change init sequence ordering
In preparation for using per device work queues, we need to move the
start of the neighbor thread task to after ipoib_ib_dev_init and move
the destruction of the neighbor task to before ipoib_ib_dev_cleanup.
Otherwise we will end up freeing our workqueue with work possibly
still on it.
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 58b5aa3b6f2d..2cf81ef51412 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -1262,15 +1262,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
1262 | { | 1262 | { |
1263 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1263 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
1264 | 1264 | ||
1265 | if (ipoib_neigh_hash_init(priv) < 0) | ||
1266 | goto out; | ||
1267 | /* Allocate RX/TX "rings" to hold queued skbs */ | 1265 | /* Allocate RX/TX "rings" to hold queued skbs */ |
1268 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, | 1266 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, |
1269 | GFP_KERNEL); | 1267 | GFP_KERNEL); |
1270 | if (!priv->rx_ring) { | 1268 | if (!priv->rx_ring) { |
1271 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", | 1269 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", |
1272 | ca->name, ipoib_recvq_size); | 1270 | ca->name, ipoib_recvq_size); |
1273 | goto out_neigh_hash_cleanup; | 1271 | goto out; |
1274 | } | 1272 | } |
1275 | 1273 | ||
1276 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); | 1274 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); |
@@ -1285,16 +1283,24 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
1285 | if (ipoib_ib_dev_init(dev, ca, port)) | 1283 | if (ipoib_ib_dev_init(dev, ca, port)) |
1286 | goto out_tx_ring_cleanup; | 1284 | goto out_tx_ring_cleanup; |
1287 | 1285 | ||
1286 | /* | ||
1287 | * Must be after ipoib_ib_dev_init so we can allocate a per | ||
1288 | * device wq there and use it here | ||
1289 | */ | ||
1290 | if (ipoib_neigh_hash_init(priv) < 0) | ||
1291 | goto out_dev_uninit; | ||
1292 | |||
1288 | return 0; | 1293 | return 0; |
1289 | 1294 | ||
1295 | out_dev_uninit: | ||
1296 | ipoib_ib_dev_cleanup(); | ||
1297 | |||
1290 | out_tx_ring_cleanup: | 1298 | out_tx_ring_cleanup: |
1291 | vfree(priv->tx_ring); | 1299 | vfree(priv->tx_ring); |
1292 | 1300 | ||
1293 | out_rx_ring_cleanup: | 1301 | out_rx_ring_cleanup: |
1294 | kfree(priv->rx_ring); | 1302 | kfree(priv->rx_ring); |
1295 | 1303 | ||
1296 | out_neigh_hash_cleanup: | ||
1297 | ipoib_neigh_hash_uninit(dev); | ||
1298 | out: | 1304 | out: |
1299 | return -ENOMEM; | 1305 | return -ENOMEM; |
1300 | } | 1306 | } |
@@ -1317,6 +1323,12 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
1317 | } | 1323 | } |
1318 | unregister_netdevice_many(&head); | 1324 | unregister_netdevice_many(&head); |
1319 | 1325 | ||
1326 | /* | ||
1327 | * Must be before ipoib_ib_dev_cleanup or we delete an in use | ||
1328 | * work queue | ||
1329 | */ | ||
1330 | ipoib_neigh_hash_uninit(dev); | ||
1331 | |||
1320 | ipoib_ib_dev_cleanup(dev); | 1332 | ipoib_ib_dev_cleanup(dev); |
1321 | 1333 | ||
1322 | kfree(priv->rx_ring); | 1334 | kfree(priv->rx_ring); |
@@ -1324,8 +1336,6 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
1324 | 1336 | ||
1325 | priv->rx_ring = NULL; | 1337 | priv->rx_ring = NULL; |
1326 | priv->tx_ring = NULL; | 1338 | priv->tx_ring = NULL; |
1327 | |||
1328 | ipoib_neigh_hash_uninit(dev); | ||
1329 | } | 1339 | } |
1330 | 1340 | ||
1331 | static const struct header_ops ipoib_header_ops = { | 1341 | static const struct header_ops ipoib_header_ops = { |