aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2009-01-14 17:55:41 -0500
committerRoland Dreier <rolandd@cisco.com>2009-01-14 17:55:41 -0500
commitb8a1b1ce14252b59b2d5c89de25b54f9bfd4cc5e (patch)
treeb3bf96fe0646bd30684391f1f9565347566cdd0c
parente0b325d310a6b11f1538413fd557d2eb98f2fae5 (diff)
IPoIB: Fix hang in napi_disable() if P_Key is never found
After commit fe25c561 ("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>
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index dce0443f9d69..0bd2a4ff0842 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -106,23 +106,17 @@ int ipoib_open(struct net_device *dev)
106 106
107 ipoib_dbg(priv, "bringing up interface\n"); 107 ipoib_dbg(priv, "bringing up interface\n");
108 108
109 set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); 109 if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
110 napi_enable(&priv->napi);
110 111
111 if (ipoib_pkey_dev_delay_open(dev)) 112 if (ipoib_pkey_dev_delay_open(dev))
112 return 0; 113 return 0;
113 114
114 napi_enable(&priv->napi); 115 if (ipoib_ib_dev_open(dev))
116 goto err_disable;
115 117
116 if (ipoib_ib_dev_open(dev)) { 118 if (ipoib_ib_dev_up(dev))
117 napi_disable(&priv->napi); 119 goto err_stop;
118 return -EINVAL;
119 }
120
121 if (ipoib_ib_dev_up(dev)) {
122 ipoib_ib_dev_stop(dev, 1);
123 napi_disable(&priv->napi);
124 return -EINVAL;
125 }
126 120
127 if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { 121 if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
128 struct ipoib_dev_priv *cpriv; 122 struct ipoib_dev_priv *cpriv;
@@ -144,6 +138,15 @@ int ipoib_open(struct net_device *dev)
144 netif_start_queue(dev); 138 netif_start_queue(dev);
145 139
146 return 0; 140 return 0;
141
142err_stop:
143 ipoib_ib_dev_stop(dev, 1);
144
145err_disable:
146 napi_disable(&priv->napi);
147 clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
148
149 return -EINVAL;
147} 150}
148 151
149static int ipoib_stop(struct net_device *dev) 152static int ipoib_stop(struct net_device *dev)