[openib-general] [PATCH/RFC 2/2] IPoIB: Convert to NAPI
Roland Dreier
rdreier at cisco.com
Thu Oct 19 19:37:24 PDT 2006
Convert the IP-over-InfiniBand network device driver over to using
NAPI to handle all completions (both receive and send).
Signed-off-by: Roland Dreier <rolandd at cisco.com>
---
drivers/infiniband/ulp/ipoib/ipoib.h | 1
drivers/infiniband/ulp/ipoib/ipoib_ib.c | 78 +++++++++++++++++++++++------
drivers/infiniband/ulp/ipoib/ipoib_main.c | 2 +
3 files changed, 65 insertions(+), 16 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0b8a79d..025cef2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -239,6 +239,7 @@ extern struct workqueue_struct *ipoib_wo
/* functions */
+int ipoib_poll(struct net_device *dev, int *budget);
void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8bf5e9e..7c0fe8f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -286,26 +286,58 @@ static void ipoib_ib_handle_tx_wc(struct
wc->status, wr_id, wc->vendor_err);
}
-static void ipoib_ib_handle_wc(struct net_device *dev, struct ib_wc *wc)
+int ipoib_poll(struct net_device *dev, int *budget)
{
- if (wc->wr_id & IPOIB_OP_RECV)
- ipoib_ib_handle_rx_wc(dev, wc);
- else
- ipoib_ib_handle_tx_wc(dev, wc);
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+ int max = min(*budget, dev->quota);
+ int done;
+ int t;
+ int empty;
+ int n, i;
+
+repoll:
+ done = 0;
+ empty = 0;
+
+ while (max) {
+ t = min(IPOIB_NUM_WC, max);
+ n = ib_poll_cq(priv->cq, t, priv->ibwc);
+
+ for (i = 0; i < n; ++i) {
+ if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) {
+ ++done;
+ --max;
+ ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+ } else
+ ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+ }
+
+ if (n != t) {
+ empty = 1;
+ break;
+ }
+ }
+
+ dev->quota -= done;
+ *budget -= done;
+
+ if (empty) {
+ netif_rx_complete(dev);
+ if (unlikely(ib_req_notify_cq(priv->cq,
+ IB_CQ_NEXT_COMP |
+ IB_CQ_REPORT_MISSED_EVENTS)) &&
+ netif_rx_reschedule(dev, 0))
+ goto repoll;
+
+ return 0;
+ }
+
+ return 1;
}
void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
{
- struct net_device *dev = (struct net_device *) dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
- int n, i;
-
- ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
- do {
- n = ib_poll_cq(cq, IPOIB_NUM_WC, priv->ibwc);
- for (i = 0; i < n; ++i)
- ipoib_ib_handle_wc(dev, priv->ibwc + i);
- } while (n == IPOIB_NUM_WC);
+ netif_rx_schedule(dev_ptr);
}
static inline int post_send(struct ipoib_dev_priv *priv,
@@ -510,9 +542,10 @@ int ipoib_ib_dev_stop(struct net_device
struct ib_qp_attr qp_attr;
unsigned long begin;
struct ipoib_tx_buf *tx_req;
- int i;
+ int i, n;
clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+ netif_poll_disable(dev);
/*
* Move our QP to the error state and then reinitialize in
@@ -559,6 +592,16 @@ int ipoib_ib_dev_stop(struct net_device
goto timeout;
}
+ do {
+ n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+ for (i = 0; i < n; ++i) {
+ if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+ ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+ else
+ ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+ }
+ } while (n == IPOIB_NUM_WC);
+
msleep(1);
}
@@ -587,6 +630,9 @@ timeout:
msleep(1);
}
+ netif_poll_enable(dev);
+ ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP);
+
return 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 1eaf00e..d90aafb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -896,6 +896,8 @@ static void ipoib_setup(struct net_devic
dev->hard_header = ipoib_hard_header;
dev->set_multicast_list = ipoib_set_mcast_list;
dev->neigh_setup = ipoib_neigh_setup_dev;
+ dev->poll = ipoib_poll;
+ dev->weight = 100;
dev->watchdog_timeo = HZ;
--
1.4.1
More information about the general
mailing list