[openib-general] [PATCH] ipoib: pkt_queue
Michael S. Tsirkin
mst at mellanox.co.il
Mon Jan 16 07:37:17 PST 2006
The following patch fixes a crash we saw in testing.
It replaces ipoib_multicast_drop_counter.patch
---
Protect accesses to mcast->pkt_queue by tx_lock.
Count multicast packets removed from pkt_queue as dropped.
Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
Index: openib/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- openib.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2006-01-15 10:04:52.790884000 +0200
+++ openib/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2006-01-15 16:02:45.975223000 +0200
@@ -123,8 +123,12 @@ static void ipoib_mcast_free(struct ipoi
if (mcast->ah)
ipoib_put_ah(mcast->ah);
- while (!skb_queue_empty(&mcast->pkt_queue))
+ while (!skb_queue_empty(&mcast->pkt_queue)) {
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ ++priv->stats.tx_dropped;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
+ }
kfree(mcast);
}
@@ -276,8 +280,10 @@ static int ipoib_mcast_join_finish(struc
}
/* actually send any queued packets */
+ spin_lock_irq(&priv->tx_lock);
while (!skb_queue_empty(&mcast->pkt_queue)) {
struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
+ spin_unlock_irq(&priv->tx_lock);
skb->dev = dev;
@@ -288,7 +294,9 @@ static int ipoib_mcast_join_finish(struc
if (dev_queue_xmit(skb))
ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
+ spin_lock_irq(&priv->tx_lock);
}
+ spin_unlock_irq(&priv->tx_lock);
return 0;
}
@@ -300,6 +308,7 @@ ipoib_mcast_sendonly_join_complete(int s
{
struct ipoib_mcast *mcast = mcast_ptr;
struct net_device *dev = mcast->dev;
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
if (!status)
ipoib_mcast_join_finish(mcast, mcmember);
@@ -310,8 +319,12 @@ ipoib_mcast_sendonly_join_complete(int s
IPOIB_GID_ARG(mcast->mcmember.mgid), status);
/* Flush out any queued packets */
- while (!skb_queue_empty(&mcast->pkt_queue))
+ spin_lock_irq(&priv->tx_lock);
+ while (!skb_queue_empty(&mcast->pkt_queue)) {
+ ++priv->stats.tx_dropped;
dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
+ }
+ spin_unlock_irq(&priv->tx_lock);
/* Clear the busy flag so we try again */
clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -687,6 +700,7 @@ void ipoib_mcast_send(struct net_device
if (!mcast) {
ipoib_warn(priv, "unable to allocate memory for "
"multicast structure\n");
+ ++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
goto out;
}
@@ -700,8 +714,10 @@ void ipoib_mcast_send(struct net_device
if (!mcast->ah) {
if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
skb_queue_tail(&mcast->pkt_queue, skb);
- else
+ else {
+ ++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
+ }
if (mcast->query)
ipoib_dbg_mcast(priv, "no address vector, "
--
MST
More information about the general
mailing list