Skip to content

Commit

Permalink
IPoIB: Fix hang in napi_disable() if P_Key is never found
Browse files Browse the repository at this point in the history
After commit fe25c56 ("IPoIB: Don't enable NAPI when it's already
enabled"), if an interface is brought up but the corresponding P_Key
never appears, then ipoib_stop() will hang in napi_disable(), because
ipoib_open() returns before it does napi_enable().

Fix this by changing ipoib_open() to call napi_enable() even if the
P_Key isn't present.

Reported-by: Yossi Etigin <yosefe@Voltaire.COM>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Roland Dreier committed Jan 14, 2009
1 parent e0b325d commit b8a1b1c
Showing 1 changed file with 15 additions and 12 deletions.
27 changes: 15 additions & 12 deletions drivers/infiniband/ulp/ipoib/ipoib_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,23 +106,17 @@ int ipoib_open(struct net_device *dev)

ipoib_dbg(priv, "bringing up interface\n");

set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
napi_enable(&priv->napi);

if (ipoib_pkey_dev_delay_open(dev))
return 0;

napi_enable(&priv->napi);
if (ipoib_ib_dev_open(dev))
goto err_disable;

if (ipoib_ib_dev_open(dev)) {
napi_disable(&priv->napi);
return -EINVAL;
}

if (ipoib_ib_dev_up(dev)) {
ipoib_ib_dev_stop(dev, 1);
napi_disable(&priv->napi);
return -EINVAL;
}
if (ipoib_ib_dev_up(dev))
goto err_stop;

if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
struct ipoib_dev_priv *cpriv;
Expand All @@ -144,6 +138,15 @@ int ipoib_open(struct net_device *dev)
netif_start_queue(dev);

return 0;

err_stop:
ipoib_ib_dev_stop(dev, 1);

err_disable:
napi_disable(&priv->napi);
clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);

return -EINVAL;
}

static int ipoib_stop(struct net_device *dev)
Expand Down

0 comments on commit b8a1b1c

Please sign in to comment.