[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