diff options
author | Doug Ledford <dledford@redhat.com> | 2015-02-21 19:27:00 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-04-15 16:06:17 -0400 |
commit | be7aa663fc1d9156798f5af3c60e6df45e1fe5de (patch) | |
tree | b359b4429be35816f0abf9889942e02933c59e84 | |
parent | e135106fac9525352feb8e49077c8f46c3eaf288 (diff) |
IB/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>
-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 657b89b1d291..98c738d827d1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -1269,15 +1269,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
1269 | { | 1269 | { |
1270 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1270 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
1271 | 1271 | ||
1272 | if (ipoib_neigh_hash_init(priv) < 0) | ||
1273 | goto out; | ||
1274 | /* Allocate RX/TX "rings" to hold queued skbs */ | 1272 | /* Allocate RX/TX "rings" to hold queued skbs */ |
1275 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, | 1273 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, |
1276 | GFP_KERNEL); | 1274 | GFP_KERNEL); |
1277 | if (!priv->rx_ring) { | 1275 | if (!priv->rx_ring) { |
1278 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", | 1276 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", |
1279 | ca->name, ipoib_recvq_size); | 1277 | ca->name, ipoib_recvq_size); |
1280 | goto out_neigh_hash_cleanup; | 1278 | goto out; |
1281 | } | 1279 | } |
1282 | 1280 | ||
1283 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); | 1281 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); |
@@ -1292,16 +1290,24 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
1292 | if (ipoib_ib_dev_init(dev, ca, port)) | 1290 | if (ipoib_ib_dev_init(dev, ca, port)) |
1293 | goto out_tx_ring_cleanup; | 1291 | goto out_tx_ring_cleanup; |
1294 | 1292 | ||
1293 | /* | ||
1294 | * Must be after ipoib_ib_dev_init so we can allocate a per | ||
1295 | * device wq there and use it here | ||
1296 | */ | ||
1297 | if (ipoib_neigh_hash_init(priv) < 0) | ||
1298 | goto out_dev_uninit; | ||
1299 | |||
1295 | return 0; | 1300 | return 0; |
1296 | 1301 | ||
1302 | out_dev_uninit: | ||
1303 | ipoib_ib_dev_cleanup(dev); | ||
1304 | |||
1297 | out_tx_ring_cleanup: | 1305 | out_tx_ring_cleanup: |
1298 | vfree(priv->tx_ring); | 1306 | vfree(priv->tx_ring); |
1299 | 1307 | ||
1300 | out_rx_ring_cleanup: | 1308 | out_rx_ring_cleanup: |
1301 | kfree(priv->rx_ring); | 1309 | kfree(priv->rx_ring); |
1302 | 1310 | ||
1303 | out_neigh_hash_cleanup: | ||
1304 | ipoib_neigh_hash_uninit(dev); | ||
1305 | out: | 1311 | out: |
1306 | return -ENOMEM; | 1312 | return -ENOMEM; |
1307 | } | 1313 | } |
@@ -1324,6 +1330,12 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
1324 | } | 1330 | } |
1325 | unregister_netdevice_many(&head); | 1331 | unregister_netdevice_many(&head); |
1326 | 1332 | ||
1333 | /* | ||
1334 | * Must be before ipoib_ib_dev_cleanup or we delete an in use | ||
1335 | * work queue | ||
1336 | */ | ||
1337 | ipoib_neigh_hash_uninit(dev); | ||
1338 | |||
1327 | ipoib_ib_dev_cleanup(dev); | 1339 | ipoib_ib_dev_cleanup(dev); |
1328 | 1340 | ||
1329 | kfree(priv->rx_ring); | 1341 | kfree(priv->rx_ring); |
@@ -1331,8 +1343,6 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
1331 | 1343 | ||
1332 | priv->rx_ring = NULL; | 1344 | priv->rx_ring = NULL; |
1333 | priv->tx_ring = NULL; | 1345 | priv->tx_ring = NULL; |
1334 | |||
1335 | ipoib_neigh_hash_uninit(dev); | ||
1336 | } | 1346 | } |
1337 | 1347 | ||
1338 | static const struct header_ops ipoib_header_ops = { | 1348 | static const struct header_ops ipoib_header_ops = { |