aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_cm.c
diff options
context:
space:
mode:
authorEli Cohen <eli@mellanox.co.il>2010-03-03 07:27:52 -0500
committerRoland Dreier <rolandd@cisco.com>2010-03-11 16:37:11 -0500
commitf0dc117abdfa9a0e96c3d013d836460ef3cd08c7 (patch)
treeba9d3b44ee1b8a63cabed9ef9c4f5710f6507eb9 /drivers/infiniband/ulp/ipoib/ipoib_cm.c
parent25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff)
IPoIB: Fix TX queue lockup with mixed UD/CM traffic
The IPoIB UD QP reports send completions to priv->send_cq, which is usually left unarmed; it only gets armed when the number of outstanding send requests reaches the size of the TX queue. This arming is done only in the send path for the UD QP. However, when sending CM packets, the net queue may be stopped for the same reasons but no measures are taken to recover the UD path from a lockup. Consider this scenario: a host sends high rate of both CM and UD packets, with a TX queue length of N. If at some time the number of outstanding UD packets is more than N/2 and the overall outstanding packets is N-1, and CM sends a packet (making the number of outstanding sends equal N), the TX queue will be stopped. When all the CM packets complete, the number of outstanding packets will still be higher than N/2 so the TX queue will not be restarted. Fix this by calling ib_req_notify_cq() when the queue is stopped in the CM path. Signed-off-by: Eli Cohen <eli@mellanox.co.il> 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.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 83a7751c38d6..6e3cc865e369 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -752,6 +752,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
752 if (++priv->tx_outstanding == ipoib_sendq_size) { 752 if (++priv->tx_outstanding == ipoib_sendq_size) {
753 ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", 753 ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
754 tx->qp->qp_num); 754 tx->qp->qp_num);
755 if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
756 ipoib_warn(priv, "request notify on send CQ failed\n");
755 netif_stop_queue(dev); 757 netif_stop_queue(dev);
756 } 758 }
757 } 759 }