aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_cm.c
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2008-09-30 13:36:21 -0400
committerRoland Dreier <rolandd@cisco.com>2008-09-30 13:36:21 -0400
commit943c246e9ba9078a61b6bcc5b4a8131ce8befb64 (patch)
tree5be6015188c06d14ff39ac85f28f58834d001d05 /drivers/infiniband/ulp/ipoib/ipoib_cm.c
parentc9da4bad5b80c3d9884e2c6ad8d2091252c32d5e (diff)
IPoIB: Use netif_tx_lock() and get rid of private tx_lock, LLTX
Currently, IPoIB is an LLTX driver that uses its own IRQ-disabling tx_lock. Not only do we want to get rid of LLTX, this actually causes problems because of the skb_orphan() done with this tx_lock held: some skb destructors expect to be run with interrupts enabled. The simplest fix for this is to get rid of the driver-private tx_lock and stop using LLTX. We kill off priv->tx_lock and use netif_tx_lock[_bh]() instead; the patch to do this is a tiny bit tricky because we need to update places that take priv->lock inside the tx_lock to disable IRQs, rather than relying on tx_lock having already disabled IRQs. Also, there are a couple of places where we need to disable BHs to make sure we have a consistent context to call netif_tx_lock() (since we no longer can use _irqsave() variants), and we also have to change ipoib_send_comp_handler() to call drain_tx_cq() through a timer rather than directly, because ipoib_send_comp_handler() runs in interrupt context and drain_tx_cq() must run in BH context so it can call netif_tx_lock(). Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_cm.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 341ffedafed6..7b14c2c39500 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -786,7 +786,8 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
786 786
787 dev_kfree_skb_any(tx_req->skb); 787 dev_kfree_skb_any(tx_req->skb);
788 788
789 spin_lock_irqsave(&priv->tx_lock, flags); 789 netif_tx_lock(dev);
790
790 ++tx->tx_tail; 791 ++tx->tx_tail;
791 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && 792 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
792 netif_queue_stopped(dev) && 793 netif_queue_stopped(dev) &&
@@ -801,7 +802,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
801 "(status=%d, wrid=%d vend_err %x)\n", 802 "(status=%d, wrid=%d vend_err %x)\n",
802 wc->status, wr_id, wc->vendor_err); 803 wc->status, wr_id, wc->vendor_err);
803 804
804 spin_lock(&priv->lock); 805 spin_lock_irqsave(&priv->lock, flags);
805 neigh = tx->neigh; 806 neigh = tx->neigh;
806 807
807 if (neigh) { 808 if (neigh) {
@@ -821,10 +822,10 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
821 822
822 clear_bit(IPOIB_FLAG_OPER_UP, &tx->flags); 823 clear_bit(IPOIB_FLAG_OPER_UP, &tx->flags);
823 824
824 spin_unlock(&priv->lock); 825 spin_unlock_irqrestore(&priv->lock, flags);
825 } 826 }
826 827
827 spin_unlock_irqrestore(&priv->tx_lock, flags); 828 netif_tx_unlock(dev);
828} 829}
829 830
830int ipoib_cm_dev_open(struct net_device *dev) 831int ipoib_cm_dev_open(struct net_device *dev)
@@ -1149,7 +1150,6 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
1149{ 1150{
1150 struct ipoib_dev_priv *priv = netdev_priv(p->dev); 1151 struct ipoib_dev_priv *priv = netdev_priv(p->dev);
1151 struct ipoib_cm_tx_buf *tx_req; 1152 struct ipoib_cm_tx_buf *tx_req;
1152 unsigned long flags;
1153 unsigned long begin; 1153 unsigned long begin;
1154 1154
1155 ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n", 1155 ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n",
@@ -1180,12 +1180,12 @@ timeout:
1180 DMA_TO_DEVICE); 1180 DMA_TO_DEVICE);
1181 dev_kfree_skb_any(tx_req->skb); 1181 dev_kfree_skb_any(tx_req->skb);
1182 ++p->tx_tail; 1182 ++p->tx_tail;
1183 spin_lock_irqsave(&priv->tx_lock, flags); 1183 netif_tx_lock_bh(p->dev);
1184 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && 1184 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
1185 netif_queue_stopped(p->dev) && 1185 netif_queue_stopped(p->dev) &&
1186 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) 1186 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
1187 netif_wake_queue(p->dev); 1187 netif_wake_queue(p->dev);
1188 spin_unlock_irqrestore(&priv->tx_lock, flags); 1188 netif_tx_unlock_bh(p->dev);
1189 } 1189 }
1190 1190
1191 if (p->qp) 1191 if (p->qp)
@@ -1202,6 +1202,7 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
1202 struct ipoib_dev_priv *priv = netdev_priv(tx->dev); 1202 struct ipoib_dev_priv *priv = netdev_priv(tx->dev);
1203 struct net_device *dev = priv->dev; 1203 struct net_device *dev = priv->dev;
1204 struct ipoib_neigh *neigh; 1204 struct ipoib_neigh *neigh;
1205 unsigned long flags;
1205 int ret; 1206 int ret;
1206 1207
1207 switch (event->event) { 1208 switch (event->event) {
@@ -1220,8 +1221,8 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
1220 case IB_CM_REJ_RECEIVED: 1221 case IB_CM_REJ_RECEIVED:
1221 case IB_CM_TIMEWAIT_EXIT: 1222 case IB_CM_TIMEWAIT_EXIT:
1222 ipoib_dbg(priv, "CM error %d.\n", event->event); 1223 ipoib_dbg(priv, "CM error %d.\n", event->event);
1223 spin_lock_irq(&priv->tx_lock); 1224 netif_tx_lock_bh(dev);
1224 spin_lock(&priv->lock); 1225 spin_lock_irqsave(&priv->lock, flags);
1225 neigh = tx->neigh; 1226 neigh = tx->neigh;
1226 1227
1227 if (neigh) { 1228 if (neigh) {
@@ -1239,8 +1240,8 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
1239 queue_work(ipoib_workqueue, &priv->cm.reap_task); 1240 queue_work(ipoib_workqueue, &priv->cm.reap_task);
1240 } 1241 }
1241 1242
1242 spin_unlock(&priv->lock); 1243 spin_unlock_irqrestore(&priv->lock, flags);
1243 spin_unlock_irq(&priv->tx_lock); 1244 netif_tx_unlock_bh(dev);
1244 break; 1245 break;
1245 default: 1246 default:
1246 break; 1247 break;
@@ -1294,19 +1295,24 @@ static void ipoib_cm_tx_start(struct work_struct *work)
1294 struct ib_sa_path_rec pathrec; 1295 struct ib_sa_path_rec pathrec;
1295 u32 qpn; 1296 u32 qpn;
1296 1297
1297 spin_lock_irqsave(&priv->tx_lock, flags); 1298 netif_tx_lock_bh(dev);
1298 spin_lock(&priv->lock); 1299 spin_lock_irqsave(&priv->lock, flags);
1300
1299 while (!list_empty(&priv->cm.start_list)) { 1301 while (!list_empty(&priv->cm.start_list)) {
1300 p = list_entry(priv->cm.start_list.next, typeof(*p), list); 1302 p = list_entry(priv->cm.start_list.next, typeof(*p), list);
1301 list_del_init(&p->list); 1303 list_del_init(&p->list);
1302 neigh = p->neigh; 1304 neigh = p->neigh;
1303 qpn = IPOIB_QPN(neigh->neighbour->ha); 1305 qpn = IPOIB_QPN(neigh->neighbour->ha);
1304 memcpy(&pathrec, &p->path->pathrec, sizeof pathrec); 1306 memcpy(&pathrec, &p->path->pathrec, sizeof pathrec);
1305 spin_unlock(&priv->lock); 1307
1306 spin_unlock_irqrestore(&priv->tx_lock, flags); 1308 spin_unlock_irqrestore(&priv->lock, flags);
1309 netif_tx_unlock_bh(dev);
1310
1307 ret = ipoib_cm_tx_init(p, qpn, &pathrec); 1311 ret = ipoib_cm_tx_init(p, qpn, &pathrec);
1308 spin_lock_irqsave(&priv->tx_lock, flags); 1312
1309 spin_lock(&priv->lock); 1313 netif_tx_lock_bh(dev);
1314 spin_lock_irqsave(&priv->lock, flags);
1315
1310 if (ret) { 1316 if (ret) {
1311 neigh = p->neigh; 1317 neigh = p->neigh;
1312 if (neigh) { 1318 if (neigh) {
@@ -1320,44 +1326,52 @@ static void ipoib_cm_tx_start(struct work_struct *work)
1320 kfree(p); 1326 kfree(p);
1321 } 1327 }
1322 } 1328 }
1323 spin_unlock(&priv->lock); 1329
1324 spin_unlock_irqrestore(&priv->tx_lock, flags); 1330 spin_unlock_irqrestore(&priv->lock, flags);
1331 netif_tx_unlock_bh(dev);
1325} 1332}
1326 1333
1327static void ipoib_cm_tx_reap(struct work_struct *work) 1334static void ipoib_cm_tx_reap(struct work_struct *work)
1328{ 1335{
1329 struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, 1336 struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
1330 cm.reap_task); 1337 cm.reap_task);
1338 struct net_device *dev = priv->dev;
1331 struct ipoib_cm_tx *p; 1339 struct ipoib_cm_tx *p;
1340 unsigned long flags;
1341
1342 netif_tx_lock_bh(dev);
1343 spin_lock_irqsave(&priv->lock, flags);
1332 1344
1333 spin_lock_irq(&priv->tx_lock);
1334 spin_lock(&priv->lock);
1335 while (!list_empty(&priv->cm.reap_list)) { 1345 while (!list_empty(&priv->cm.reap_list)) {
1336 p = list_entry(priv->cm.reap_list.next, typeof(*p), list); 1346 p = list_entry(priv->cm.reap_list.next, typeof(*p), list);
1337 list_del(&p->list); 1347 list_del(&p->list);
1338 spin_unlock(&priv->lock); 1348 spin_unlock_irqrestore(&priv->lock, flags);
1339 spin_unlock_irq(&priv->tx_lock); 1349 netif_tx_unlock_bh(dev);
1340 ipoib_cm_tx_destroy(p); 1350 ipoib_cm_tx_destroy(p);
1341 spin_lock_irq(&priv->tx_lock); 1351 netif_tx_lock_bh(dev);
1342 spin_lock(&priv->lock); 1352 spin_lock_irqsave(&priv->lock, flags);
1343 } 1353 }
1344 spin_unlock(&priv->lock); 1354
1345 spin_unlock_irq(&priv->tx_lock); 1355 spin_unlock_irqrestore(&priv->lock, flags);
1356 netif_tx_unlock_bh(dev);
1346} 1357}
1347 1358
1348static void ipoib_cm_skb_reap(struct work_struct *work) 1359static void ipoib_cm_skb_reap(struct work_struct *work)
1349{ 1360{
1350 struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, 1361 struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
1351 cm.skb_task); 1362 cm.skb_task);
1363 struct net_device *dev = priv->dev;
1352 struct sk_buff *skb; 1364 struct sk_buff *skb;
1353 1365 unsigned long flags;
1354 unsigned mtu = priv->mcast_mtu; 1366 unsigned mtu = priv->mcast_mtu;
1355 1367
1356 spin_lock_irq(&priv->tx_lock); 1368 netif_tx_lock_bh(dev);
1357 spin_lock(&priv->lock); 1369 spin_lock_irqsave(&priv->lock, flags);
1370
1358 while ((skb = skb_dequeue(&priv->cm.skb_queue))) { 1371 while ((skb = skb_dequeue(&priv->cm.skb_queue))) {
1359 spin_unlock(&priv->lock); 1372 spin_unlock_irqrestore(&priv->lock, flags);
1360 spin_unlock_irq(&priv->tx_lock); 1373 netif_tx_unlock_bh(dev);
1374
1361 if (skb->protocol == htons(ETH_P_IP)) 1375 if (skb->protocol == htons(ETH_P_IP))
1362 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 1376 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
1363#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1377#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -1365,11 +1379,13 @@ static void ipoib_cm_skb_reap(struct work_struct *work)
1365 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev); 1379 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev);
1366#endif 1380#endif
1367 dev_kfree_skb_any(skb); 1381 dev_kfree_skb_any(skb);
1368 spin_lock_irq(&priv->tx_lock); 1382
1369 spin_lock(&priv->lock); 1383 netif_tx_lock_bh(dev);
1384 spin_lock_irqsave(&priv->lock, flags);
1370 } 1385 }
1371 spin_unlock(&priv->lock); 1386
1372 spin_unlock_irq(&priv->tx_lock); 1387 spin_unlock_irqrestore(&priv->lock, flags);
1388 netif_tx_unlock_bh(dev);
1373} 1389}
1374 1390
1375void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, 1391void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,