Skip to content

Commit 3bcce48

Browse files
dledfordrolandd
authored andcommitted
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 <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent e5d1dcf commit 3bcce48

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

drivers/infiniband/ulp/ipoib/ipoib_main.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,15 +1262,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
12621262
{
12631263
struct ipoib_dev_priv *priv = netdev_priv(dev);
12641264

1265-
if (ipoib_neigh_hash_init(priv) < 0)
1266-
goto out;
12671265
/* Allocate RX/TX "rings" to hold queued skbs */
12681266
priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
12691267
GFP_KERNEL);
12701268
if (!priv->rx_ring) {
12711269
printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
12721270
ca->name, ipoib_recvq_size);
1273-
goto out_neigh_hash_cleanup;
1271+
goto out;
12741272
}
12751273

12761274
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)
12851283
if (ipoib_ib_dev_init(dev, ca, port))
12861284
goto out_tx_ring_cleanup;
12871285

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+
12881293
return 0;
12891294

1295+
out_dev_uninit:
1296+
ipoib_ib_dev_cleanup();
1297+
12901298
out_tx_ring_cleanup:
12911299
vfree(priv->tx_ring);
12921300

12931301
out_rx_ring_cleanup:
12941302
kfree(priv->rx_ring);
12951303

1296-
out_neigh_hash_cleanup:
1297-
ipoib_neigh_hash_uninit(dev);
12981304
out:
12991305
return -ENOMEM;
13001306
}
@@ -1317,15 +1323,19 @@ void ipoib_dev_cleanup(struct net_device *dev)
13171323
}
13181324
unregister_netdevice_many(&head);
13191325

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+
13201332
ipoib_ib_dev_cleanup(dev);
13211333

13221334
kfree(priv->rx_ring);
13231335
vfree(priv->tx_ring);
13241336

13251337
priv->rx_ring = NULL;
13261338
priv->tx_ring = NULL;
1327-
1328-
ipoib_neigh_hash_uninit(dev);
13291339
}
13301340

13311341
static const struct header_ops ipoib_header_ops = {

0 commit comments

Comments
 (0)