|
@@ -97,6 +97,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
|
|
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
|
|
struct ipoib_neigh *neigh, *tmp;
|
|
|
unsigned long flags;
|
|
|
+ int tx_dropped = 0;
|
|
|
|
|
|
ipoib_dbg_mcast(netdev_priv(dev),
|
|
|
"deleting multicast group " IPOIB_GID_FMT "\n",
|
|
@@ -123,8 +124,14 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
|
|
|
if (mcast->ah)
|
|
|
ipoib_put_ah(mcast->ah);
|
|
|
|
|
|
- while (!skb_queue_empty(&mcast->pkt_queue))
|
|
|
+ while (!skb_queue_empty(&mcast->pkt_queue)) {
|
|
|
+ ++tx_dropped;
|
|
|
dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock_irqsave(&priv->tx_lock, flags);
|
|
|
+ priv->stats.tx_dropped += tx_dropped;
|
|
|
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
|
|
|
|
|
|
kfree(mcast);
|
|
|
}
|
|
@@ -276,8 +283,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
|
|
|
}
|
|
|
|
|
|
/* 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 +297,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
|
|
|
|
|
|
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 +311,7 @@ ipoib_mcast_sendonly_join_complete(int status,
|
|
|
{
|
|
|
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 +322,12 @@ ipoib_mcast_sendonly_join_complete(int status,
|
|
|
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 +703,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
|
|
|
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 +717,10 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
|
|
|
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, "
|