[ofa-general] [PATCH 5/5] IB/ipoib: IPOIB rx post list

Eli Cohen eli at dev.mellanox.co.il
Fri Feb 1 05:41:20 PST 2008


IB/ipoib: IPOIB rx post list
    
Post a list of RX buffers every 16 recieved packets. This
should reduce code cache trashing by make less jumps between
the hw driver to ipoib. In any case it improves UD receive flow.
    
Signed-off-by: Eli Cohen <eli at mellanox.co.il>
---

IB/ipoib: IPOIB rx post list
    
Post a list of RX buffers every 16 recieved packets. This
should reduce code cache trashing by make less jumps between
the hw driver to ipoib. In any case it improves receive flow.
    
Signed-off-by: Eli Cohen <eli at mellanox.co.il>
---

Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2008-01-31 18:49:57.000000000 +0200
+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib.h	2008-01-31 18:51:56.117198000 +0200
@@ -97,6 +97,7 @@ enum {
 
 	MAX_SEND_CQE              = 16,
 	CM_POST_SRQ_COUNT         = 16,
+	UD_POST_RCV_COUNT         = 16,
 };
 
 #define	IPOIB_OP_RECV   (1ul << 31)
@@ -327,9 +328,10 @@ struct ipoib_ethtool_st {
 struct ipoib_dev_priv {
 	spinlock_t lock;
 
-	struct net_device *dev;
-	struct ib_recv_wr rx_wr_draft;
-	struct ib_sge sglist_draft;
+	struct net_device      *dev;
+	struct ib_recv_wr	rx_wr_draft[UD_POST_RCV_COUNT];
+	struct ib_sge 		sglist_draft[UD_POST_RCV_COUNT];
+	unsigned int		rx_outst;
 
 	struct napi_struct napi;
 
Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2008-01-31 18:49:57.000000000 +0200
+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2008-01-31 18:52:30.452975000 +0200
@@ -89,23 +89,45 @@ void ipoib_free_ah(struct kref *kref)
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static int ipoib_ib_post_receive(struct net_device *dev, int id)
+static void clean_pending_receives(struct ipoib_dev_priv *priv)
 {
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	struct ib_recv_wr *bad_wr;
-	int ret;
-
-	priv->sglist_draft.addr = priv->rx_ring[id].mapping;
-	priv->rx_wr_draft.wr_id = id | IPOIB_OP_RECV;
+	int i;
+	int id;
 
-	ret = ib_post_recv(priv->qp, &priv->rx_wr_draft, &bad_wr);
-	if (unlikely(ret)) {
-		ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret);
+	for (i = 0; i < priv->rx_outst; ++i) {
+		id = priv->rx_wr_draft[i].wr_id & ~IPOIB_OP_RECV;
 		ib_dma_unmap_single(priv->ca, priv->rx_ring[id].mapping,
-				    IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+                                            IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
 		dev_kfree_skb_any(priv->rx_ring[id].skb);
 		priv->rx_ring[id].skb = NULL;
 	}
+	priv->rx_outst = 0;
+}
+
+static int ipoib_ib_post_receive(struct net_device *dev, int id)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_recv_wr *bad_wr;
+	int ret = 0;
+	int i = priv->rx_outst;
+
+	priv->sglist_draft[i].addr = priv->rx_ring[id].mapping;
+	priv->rx_wr_draft[i].wr_id = id | IPOIB_OP_RECV;
+	if (++priv->rx_outst == UD_POST_RCV_COUNT) {
+		ret = ib_post_recv(priv->qp, priv->rx_wr_draft, &bad_wr);
+
+		if (unlikely(ret)) {
+			ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret);
+			while (bad_wr) {
+				id = bad_wr->wr_id & ~IPOIB_OP_RECV;
+				ib_dma_unmap_single(priv->ca, priv->rx_ring[id].mapping,
+						    IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+				dev_kfree_skb_any(priv->rx_ring[id].skb);
+				priv->rx_ring[id].skb = NULL;
+			}
+		}
+		priv->rx_outst = 0;
+	}
 
 	return ret;
 }
@@ -791,6 +813,7 @@ int ipoib_ib_dev_stop(struct net_device 
 	if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
 		ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
 
+	clean_pending_receives(priv);
 	/* Wait for all sends and receives to complete */
 	begin = jiffies;
 
Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
===================================================================
--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2008-01-31 18:49:57.000000000 +0200
+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2008-01-31 18:51:13.310744000 +0200
@@ -222,12 +222,16 @@ int ipoib_transport_dev_init(struct net_
 	priv->tx_wr.sg_list 	= priv->tx_sge;
 	priv->tx_wr.send_flags 	= IB_SEND_SIGNALED;
 
-	priv->rx_wr_draft.next = NULL;
-	priv->rx_wr_draft.sg_list = &priv->sglist_draft;
-	priv->rx_wr_draft.num_sge = 1;
-
-	priv->sglist_draft.length = IPOIB_BUF_SIZE;
-	priv->sglist_draft.lkey = priv->mr->lkey;
+	for (i = 0; i < UD_POST_RCV_COUNT; ++i) {
+		priv->sglist_draft[i].length = IPOIB_BUF_SIZE;
+		priv->sglist_draft[i].lkey = priv->mr->lkey;
+
+		priv->rx_wr_draft[i].sg_list = &priv->sglist_draft[i];
+		priv->rx_wr_draft[i].num_sge = 1;
+		if (i < UD_POST_RCV_COUNT - 1)
+			priv->rx_wr_draft[i].next = &priv->rx_wr_draft[i + 1];
+	}
+	priv->rx_wr_draft[i].next = NULL;
 
 	return 0;
 





More information about the general mailing list