RDMA/cxgb3: Fix deadlock in iw_cxgb3 (hang when configuring interface)

When the iw_cxgb3 module's cxgb3_client "add" func gets called by the
cxgb3 module, the iwarp driver ends up calling the ethtool ops
get_drvinfo function in cxgb3 to get the fw version and other info.
Currently the iwarp driver grabs the rtnl lock around this down call
to serialize. As of 2.6.27 or so, things changed such that the rtnl
lock is held around the call to the netdev driver open function. Also
the cxgb3_client "add" function doesn't get called if the device is
down.

So, if you load cxgb3, then load iw_cxgb3, then ifconfig up the
device, the iw_cxgb3 add func gets called with the rtnl_lock held. If
you load cxgb3, ifconfig up the device, then load iw_cxgb3, the add
func gets called without the rtnl_lock held. The former causes the
deadlock, the latter does not.

In addition, there are iw_cxgb3 sysfs handlers that also can call down
into cxgb3 to gather the fw and hw versions. These can be called
concurrently on different processors and at any time. Thus we need to
push this serialization down in the cxgb3 driver get_drvinfo func.

The fix is to remove rtnl lock usage, and use a per-device lock in cxgb3.

Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Acked-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Steve Wise and committed by Roland Dreier b3e123cf af2b0a1e

+2 -6
-6
drivers/infiniband/hw/cxgb3/iwch_provider.c
··· 1102 1102 char *cp, *next; 1103 1103 unsigned fw_maj, fw_min, fw_mic; 1104 1104 1105 - rtnl_lock(); 1106 1105 lldev->ethtool_ops->get_drvinfo(lldev, &info); 1107 - rtnl_unlock(); 1108 1106 1109 1107 next = info.fw_version + 1; 1110 1108 cp = strsep(&next, "."); ··· 1190 1192 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; 1191 1193 1192 1194 PDBG("%s dev 0x%p\n", __func__, dev); 1193 - rtnl_lock(); 1194 1195 lldev->ethtool_ops->get_drvinfo(lldev, &info); 1195 - rtnl_unlock(); 1196 1196 return sprintf(buf, "%s\n", info.fw_version); 1197 1197 } 1198 1198 ··· 1203 1207 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; 1204 1208 1205 1209 PDBG("%s dev 0x%p\n", __func__, dev); 1206 - rtnl_lock(); 1207 1210 lldev->ethtool_ops->get_drvinfo(lldev, &info); 1208 - rtnl_unlock(); 1209 1211 return sprintf(buf, "%s\n", info.driver); 1210 1212 } 1211 1213
+2
drivers/net/cxgb3/cxgb3_main.c
··· 1307 1307 u32 fw_vers = 0; 1308 1308 u32 tp_vers = 0; 1309 1309 1310 + spin_lock(&adapter->stats_lock); 1310 1311 t3_get_fw_version(adapter, &fw_vers); 1311 1312 t3_get_tp_version(adapter, &tp_vers); 1313 + spin_unlock(&adapter->stats_lock); 1312 1314 1313 1315 strcpy(info->driver, DRV_NAME); 1314 1316 strcpy(info->version, DRV_VERSION);