提交 1b844afe 编写于 作者: R Roland Dreier

IPoIB: Recycle loopback skbs instead of freeing and reallocating

InfiniBand HCAs replicate multicast packets back to the QP that sent
them if that QP is attached to the destination multicast group.  This
means that IPoIB multicasts are often replicated back to the receive
queue of the interface that generated them.  To avoid confusing the
network stack, we drop these duplicates within the IPoIB driver.

However, there's no reason to free the skb that received the duplicate
and then immediately allocate a new skb to post to the receive queue.
We can be more efficient and just repost the same skb.
Signed-off-by: NRoland Dreier <rolandd@cisco.com>
上级 8909c571
...@@ -196,6 +196,13 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) ...@@ -196,6 +196,13 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
return; return;
} }
/*
* Drop packets that this interface sent, ie multicast packets
* that the HCA has replicated.
*/
if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num)
goto repost;
/* /*
* If we can't allocate a new RX buffer, dump * If we can't allocate a new RX buffer, dump
* this packet and reuse the old buffer. * this packet and reuse the old buffer.
...@@ -213,24 +220,18 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) ...@@ -213,24 +220,18 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
skb_put(skb, wc->byte_len); skb_put(skb, wc->byte_len);
skb_pull(skb, IB_GRH_BYTES); skb_pull(skb, IB_GRH_BYTES);
if (wc->slid != priv->local_lid || skb->protocol = ((struct ipoib_header *) skb->data)->proto;
wc->src_qp != priv->qp->qp_num) { skb_reset_mac_header(skb);
skb->protocol = ((struct ipoib_header *) skb->data)->proto; skb_pull(skb, IPOIB_ENCAP_LEN);
skb_reset_mac_header(skb);
skb_pull(skb, IPOIB_ENCAP_LEN);
dev->last_rx = jiffies; dev->last_rx = jiffies;
++priv->stats.rx_packets; ++priv->stats.rx_packets;
priv->stats.rx_bytes += skb->len; priv->stats.rx_bytes += skb->len;
skb->dev = dev; skb->dev = dev;
/* XXX get correct PACKET_ type here */ /* XXX get correct PACKET_ type here */
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
netif_receive_skb(skb); netif_receive_skb(skb);
} else {
ipoib_dbg_data(priv, "dropping loopback packet\n");
dev_kfree_skb_any(skb);
}
repost: repost:
if (unlikely(ipoib_ib_post_receive(dev, wr_id))) if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册