Skip to content

Commit

Permalink
IPoIB: Recycle loopback skbs instead of freeing and reallocating
Browse files Browse the repository at this point in the history
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: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Roland Dreier committed Jul 10, 2007
1 parent 8909c57 commit 1b844af
Showing 1 changed file with 17 additions and 16 deletions.
33 changes: 17 additions & 16 deletions drivers/infiniband/ulp/ipoib/ipoib_ib.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
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
* this packet and reuse the old buffer.
Expand All @@ -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_pull(skb, IB_GRH_BYTES);

if (wc->slid != priv->local_lid ||
wc->src_qp != priv->qp->qp_num) {
skb->protocol = ((struct ipoib_header *) skb->data)->proto;
skb_reset_mac_header(skb);
skb_pull(skb, IPOIB_ENCAP_LEN);
skb->protocol = ((struct ipoib_header *) skb->data)->proto;
skb_reset_mac_header(skb);
skb_pull(skb, IPOIB_ENCAP_LEN);

dev->last_rx = jiffies;
++priv->stats.rx_packets;
priv->stats.rx_bytes += skb->len;
dev->last_rx = jiffies;
++priv->stats.rx_packets;
priv->stats.rx_bytes += skb->len;

skb->dev = dev;
/* XXX get correct PACKET_ type here */
skb->pkt_type = PACKET_HOST;
netif_receive_skb(skb);
} else {
ipoib_dbg_data(priv, "dropping loopback packet\n");
dev_kfree_skb_any(skb);
}
skb->dev = dev;
/* XXX get correct PACKET_ type here */
skb->pkt_type = PACKET_HOST;
netif_receive_skb(skb);

repost:
if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
Expand Down

0 comments on commit 1b844af

Please sign in to comment.