[openib-general] [PATCH for-2.6.21] IPoIB/cm: improve small message bandwidth

Michael S. Tsirkin mst at mellanox.co.il
Sun Feb 25 04:22:11 PST 2007


> Quoting Roland Dreier <rdreier at cisco.com>:
> Subject: Re: [openib-general] [PATCH for-2.6.21] IPoIB/cm: improve small message bandwidth
> 
> OK, I applied the following patch (I had to change one line of your
> patch to get it to apply because the small-message changed the context
> so one chunk didn't apply).
> 
> Anyway I don't see any difference in small message latency or large
> message throughput.  (Actually latency seems slightly worse but I
> think the change is within my normal variability so I'm don't think
> the difference is significant)

OK.
I wonder whether unrolling the loop in skb_put_frags might be helpful.
Could you please try the following? Does this affect latency for you?
(I don't see any difference in between UD and CM either with or without
 this patch).


Try to improve small message latency some more by unrolling more loops.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

---

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index a389854..a8895b4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -311,38 +311,6 @@ static int ipoib_cm_rx_handler(struct ib_cm_id *cm_id,
 		return 0;
 	}
 }
-/* Adjust length of skb with fragments to match received data */
-static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
-			  unsigned int length, struct sk_buff *toskb)
-{
-	int i, num_frags;
-	unsigned int size;
-
-	/* put header into skb */
-	size = min(length, hdr_space);
-	skb->tail += size;
-	skb->len += size;
-	length -= size;
-
-	num_frags = skb_shinfo(skb)->nr_frags;
-	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;
-		} else {
-			size = min(length, (unsigned) PAGE_SIZE);
-
-			frag->size = size;
-			skb->data_len += size;
-			skb->truesize += size;
-			skb->len += size;
-			length -= size;
-		}
-	}
-}
 
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 {
@@ -352,7 +320,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 	struct ipoib_cm_rx *p;
 	unsigned long flags;
 	u64 mapping[IPOIB_CM_RX_SG];
-	int frags;
+	unsigned head_size, frag_size, frags;
 
 	ipoib_dbg_data(priv, "cm recv completion: id %d, op %d, status: %d\n",
 		       wr_id, wc->opcode, wc->status);
@@ -388,8 +356,9 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 		}
 	}
 
-	frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len,
-					      (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE;
+	head_size = min(wc->byte_len, (unsigned)IPOIB_CM_HEAD_SIZE);
+	frag_size = wc->byte_len - head_size;
+	frags = PAGE_ALIGN(frag_size) / PAGE_SIZE;
 
 	newskb = ipoib_cm_alloc_rx_skb(dev, wr_id, frags, mapping);
 	if (unlikely(!newskb)) {
@@ -408,7 +377,18 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 	ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
 		       wc->byte_len, wc->slid);
 
-	skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb);
+	memcpy(&skb_shinfo(newskb)->frags[frags], &skb_shinfo(skb)->frags[frags],
+	       (IPOIB_CM_RX_SG - 1 - frags) * sizeof(skb_frag_t));
+	skb_shinfo(newskb)->nr_frags = IPOIB_CM_RX_SG - 1;
+
+	skb_shinfo(skb)->nr_frags = frags;
+	skb->tail += head_size;
+	skb->len += wc->byte_len;
+	skb->data_len += frag_size;
+	skb->truesize += frag_size;
+	if (frags)
+		skb_shinfo(skb)->frags[frags - 1].size =
+			(frag_size - 1) % PAGE_SIZE + 1;
 
 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
 	skb->mac.raw = skb->data;





-- 
MST




More information about the general mailing list