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 <[EMAIL PROTECTED]>
---
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 <[EMAIL PROTECTED]>
---
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;
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general
To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general