[ofa-general] [PATCH] IB/ipoib: optimize receive flow

Eli Cohen eli at mellanox.co.il
Wed Oct 10 08:55:32 PDT 2007


Optimize IPOIB CM receive flow

This patch tries to reduce the number of accesses to the skb
object and save CPU cycles and cache misses.

Signed-off-by: Eli Cohen <eli at mellanox.co.il>

Index: ofa_kernel-1.2.5/drivers/infiniband/ulp/ipoib/ipoib_cm.c
===================================================================
--- ofa_kernel-1.2.5.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2007-10-10 15:10:27.000000000 +0200
+++ ofa_kernel-1.2.5/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2007-10-10 15:35:01.000000000 +0200
@@ -374,6 +374,8 @@ static void skb_put_frags(struct sk_buff
 {
 	int i, num_frags;
 	unsigned int size;
+	int unused_frags = 0;
+	unsigned int used_size = 0;
 
 	/* put header into skb */
 	size = min(length, hdr_space);
@@ -382,23 +384,25 @@ static void skb_put_frags(struct sk_buff
 	length -= size;
 
 	num_frags = skb_shinfo(skb)->nr_frags;
-	for (i = 0; i < num_frags; i++) {
+	for (i = 0; i < num_frags; ++i) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 		if (length == 0) {
 			/* don't need this page */
 			skb_fill_page_desc(toskb, i, frag->page, 0, PAGE_SIZE);
-			--skb_shinfo(skb)->nr_frags;
+			++unused_frags;
 		} else {
-			size = min(length, (unsigned) PAGE_SIZE);
+			size = length & PAGE_MASK ? PAGE_SIZE : length & (PAGE_SIZE - 1);
 
 			frag->size = size;
-			skb->data_len += size;
-			skb->truesize += size;
-			skb->len += size;
+			used_size += size;
 			length -= size;
 		}
 	}
+	skb->data_len += used_size;
+	skb->truesize += used_size;
+	skb->len += used_size;
+	skb_shinfo(skb)->nr_frags -= unused_frags;
 }
 
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
@@ -437,7 +441,7 @@ void ipoib_cm_handle_rx_wc(struct net_de
 		goto repost;
 	}
 
-	if (!likely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) {
+	if (unlikely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) {
 		p = wc->qp->qp_context;
 		if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) {
 			spin_lock_irqsave(&priv->lock, flags);




More information about the general mailing list