Skip to content

Commit

Permalink
IPoIB: change init sequence ordering
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Doug Ledford authored and Roland Dreier committed Dec 16, 2014
1 parent e5d1dcf commit 3bcce48
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions drivers/infiniband/ulp/ipoib/ipoib_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,15 +1262,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);

if (ipoib_neigh_hash_init(priv) < 0)
goto out;
/* Allocate RX/TX "rings" to hold queued skbs */
priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
GFP_KERNEL);
if (!priv->rx_ring) {
printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
ca->name, ipoib_recvq_size);
goto out_neigh_hash_cleanup;
goto out;
}

priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
Expand All @@ -1285,16 +1283,24 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
if (ipoib_ib_dev_init(dev, ca, port))
goto out_tx_ring_cleanup;

/*
* Must be after ipoib_ib_dev_init so we can allocate a per
* device wq there and use it here
*/
if (ipoib_neigh_hash_init(priv) < 0)
goto out_dev_uninit;

return 0;

out_dev_uninit:
ipoib_ib_dev_cleanup();

out_tx_ring_cleanup:
vfree(priv->tx_ring);

out_rx_ring_cleanup:
kfree(priv->rx_ring);

out_neigh_hash_cleanup:
ipoib_neigh_hash_uninit(dev);
out:
return -ENOMEM;
}
Expand All @@ -1317,15 +1323,19 @@ void ipoib_dev_cleanup(struct net_device *dev)
}
unregister_netdevice_many(&head);

/*
* Must be before ipoib_ib_dev_cleanup or we delete an in use
* work queue
*/
ipoib_neigh_hash_uninit(dev);

ipoib_ib_dev_cleanup(dev);

kfree(priv->rx_ring);
vfree(priv->tx_ring);

priv->rx_ring = NULL;
priv->tx_ring = NULL;

ipoib_neigh_hash_uninit(dev);
}

static const struct header_ops ipoib_header_ops = {
Expand Down

0 comments on commit 3bcce48

Please sign in to comment.