IPoIB TX NAPI
cover IPoIB TX NAPI
Changelog from v0:
* Rebase to latest for-next, commit 894b82c427d0 ("Merge branch 'timer_setup' into for-next")
----
Quoted 1 line
From Erez Shitrit <erezsh-VPRAkNaXOzVWk0Htik3J/[email protected]>
----
It is very common in modern network devices to use NAPI in RX and TX, in the UD/TX flows IPoIB uses a polling mechanism (not as it does in the CM mode).
Except of the motivation to use the same mechanism for IPoIB as for netdevices, there are number of issues in current polling mechanism:
* SKBs that are kept longer than they should be and there are applications that warn about that (some firewalls for example).
* Statistics that are not updated to the real value. It blocks support for time synchronization protocols over the IPoIB protocol, like PTP and so on.
* The TX in CM mode already uses NAPI, there is no reason to keep two different ways for TX one for UD and one for the CM.
The patches are available in the git repository at:
git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git tags/rdma-next-2017-10-19
Thanks
---------------------------------------
Erez Shitrit (3):
IB/ipoib: Get rid of the tx_outstanding variable in all modes IB/ipoib: Use NAPI in UD/TX flows
IB/ipoib: Change number of TX wqe to 64
drivers/infiniband/ulp/ipoib/ipoib.h | 14 ++-- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 46 +++++----- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 129 +++++++++++++++++------------ drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 ++++-- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 17 ++-- 5 files changed, 143 insertions(+), 87 deletions(-)
--
2.14.2
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20171019045644.5816-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
PATCH 1/3 IB/ipoib: Get rid of the tx_outstanding variable in all modes
From: Erez Shitrit <erezsh-VPRAkNaXOzVWk0Htik3J/[email protected]>
The first step toward using NAPI in the UD/TX flow is to separate between two flows, the NAPI and the xmit, meaning no use of shared variables between both flows.
This patch takes out the tx_outstanding variable that was used in both flows and instead the driver uses the 2 cyclic ring variables: tx_head and tx_tail, tx_head used in the xmit flow and tx_tail in the NAPI flow.
--- drivers/infiniband/ulp/ipoib/ipoib.h | 1 - drivers/infiniband/ulp/ipoib/ipoib_cm.c | 10 ++++++---- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 10 ++++------ 3 files changed, 10 insertions(+), 11 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib.h +0 -1
@@ -381,7 +381,6 @@ struct ipoib_dev_priv {unsigned tx_tail;struct ib_sge tx_sge[MAX_SKB_FRAGS +1 ];struct ib_ud_wr tx_wr; -unsigned tx_outstanding;struct ib_wc send_wc[MAX_SEND_CQE ];struct ib_recv_wr rx_wr;
drivers/infiniband/ulp/ipoib/ipoib_cm.c +6 -4
@@ -769,8 +769,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ }else {netif_trans_update (dev); ++tx->tx_head; - -if (++priv->tx_outstanding == ipoib_sendq_size) { + ++priv->tx_head; +if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size) {ipoib_dbg (priv,"TX ring 0x%x full, stopping kernel net queue\n" , tx->qp->qp_num);netif_stop_queue (dev);
@@ -814,7 +814,8 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)netif_tx_lock (dev); ++tx->tx_tail; -if (unlikely (--priv->tx_outstanding == ipoib_sendq_size >>1 ) && + ++priv->tx_tail; +if (unlikely ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size >>1 ) &&netif_queue_stopped (dev) &&test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags))netif_wake_queue (dev);
@@ -1220,8 +1221,9 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)ipoib_dma_unmap_tx (priv, tx_req);dev_kfree_skb_any (tx_req->skb); ++p->tx_tail; + ++priv->tx_tail;netif_tx_lock_bh (p->dev); -if (unlikely (--priv->tx_outstanding == ipoib_sendq_size >>1 ) && +if (unlikely (priv->tx_head - priv->tx_tail == ipoib_sendq_size >>1 ) &&netif_queue_stopped (p->dev) &&test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags))netif_wake_queue (p->dev);
drivers/infiniband/ulp/ipoib/ipoib_ib.c +4 -6
@@ -406,7 +406,7 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)dev_kfree_skb_any (tx_req->skb); ++priv->tx_tail; -if (unlikely (--priv->tx_outstanding == ipoib_sendq_size >>1 ) && +if (unlikely ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size >>1 ) &&netif_queue_stopped (dev) &&test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags))netif_wake_queue (dev);
@@ -611,8 +611,8 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb, priv->tx_wr.wr.send_flags |=IB_SEND_IP_CSUM ; else priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; - -if (++priv->tx_outstanding == ipoib_sendq_size) { +/* increase the tx_head after send success, but use it for queue state */ +if (priv->tx_head - priv->tx_tail == ipoib_sendq_size -1 ) {ipoib_dbg (priv,"TX ring full, stopping kernel net queue\n" );if (ib_req_notify_cq (priv->send_cq,IB_CQ_NEXT_COMP ))ipoib_warn (priv,"request notify on send CQ failed\n" );
@@ -627,7 +627,6 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb,if (unlikely (rc)) {ipoib_warn (priv,"post_send failed, error %d\n" , rc); ++dev->stats.tx_errors; - --priv->tx_outstanding;ipoib_dma_unmap_tx (priv, tx_req);dev_kfree_skb_any (skb);if (netif_queue_stopped (dev))
@@ -640,7 +639,7 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb, ++priv->tx_head; } -if (unlikely (priv->tx_outstanding >MAX_SEND_CQE )) +if (unlikely (priv->tx_head - priv->tx_tail >MAX_SEND_CQE ))while (poll_tx (priv)) ;/* nothing */
@@ -773,7 +772,6 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)ipoib_dma_unmap_tx (priv, tx_req);dev_kfree_skb_any (tx_req->skb); ++priv->tx_tail; - --priv->tx_outstanding; }for (i =0 ; i < ipoib_recvq_size; ++i) {
Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/3 IB/ipoib: Use NAPI in UD/TX flows
In reply to a message not in the archiveFrom: Erez Shitrit <erezsh-VPRAkNaXOzVWk0Htik3J/[email protected]>
Instead of explicit call to poll_cq of the tx ring, use the NAPI mechanism to handle the completions of each packet that has been sent to the HW.
The next major changes were taken:
* The driver init completion function in the creation of the send CQ, that function triggers the napi scheduling.
* The driver uses CQ for RX for both modes UD and CM, and CQ for TX for CM and UD.
--- drivers/infiniband/ulp/ipoib/ipoib.h | 11 +-- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 40 ++++++---- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 123 ++++++++++++++++++----------- drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 ++++-- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 17 ++-- 5 files changed, 136 insertions(+), 79 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib.h +6 -5
@@ -331,7 +331,8 @@ struct ipoib_dev_priv {struct net_device *dev; -struct napi_struct napi; +struct napi_struct send_napi; +struct napi_struct recv_napi;unsigned long flags;
@@ -408,7 +409,6 @@ struct ipoib_dev_priv {#endif u64 hca_caps;struct ipoib_ethtool_st ethtool; -struct timer_list poll_timer;unsigned max_send_sge;bool sm_fullmember_sendonly_support;const struct net_device_ops *rn_ops;
@@ -475,9 +475,10 @@ extern struct workqueue_struct *ipoib_workqueue;/* functions */ -int ipoib_poll (struct napi_struct *napi,int budget); -void ipoib_ib_completion (struct ib_cq *cq,void *dev_ptr); -void ipoib_send_comp_handler (struct ib_cq *cq,void *dev_ptr); +int ipoib_rx_poll (struct napi_struct *napi,int budget); +int ipoib_tx_poll (struct napi_struct *napi,int budget); +void ipoib_ib_rx_completion (struct ib_cq *cq,void *ctx_ptr); +void ipoib_ib_tx_completion (struct ib_cq *cq,void *ctx_ptr);struct ipoib_ah *ipoib_create_ah (struct net_device *dev,struct ib_pd *pd,struct rdma_ah_attr *attr);
drivers/infiniband/ulp/ipoib/ipoib_cm.c +23 -17
@@ -757,30 +757,35 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_return ; } +if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size -1 ) { +ipoib_dbg (priv,"TX ring 0x%x full, stopping kernel net queue\n" , + tx->qp->qp_num); +netif_stop_queue (dev); + } +skb_orphan (skb);skb_dst_drop (skb); +if (netif_queue_stopped (dev)) +if (ib_req_notify_cq (priv->send_cq,IB_CQ_NEXT_COMP | +IB_CQ_REPORT_MISSED_EVENTS )) { +ipoib_warn (priv,"IPoIB/CM:request notify on send CQ failed\n" ); +napi_schedule (&priv->send_napi); + } + rc =post_send (priv, tx, tx->tx_head & (ipoib_sendq_size -1 ), tx_req);if (unlikely (rc)) { -ipoib_warn (priv,"post_send failed, error %d\n" , rc); +ipoib_warn (priv,"IPoIB/CM:post_send failed, error %d\n" , rc); ++dev->stats.tx_errors;ipoib_dma_unmap_tx (priv, tx_req);dev_kfree_skb_any (skb); + +if (netif_queue_stopped (dev)) +netif_wake_queue (dev); }else {netif_trans_update (dev); ++tx->tx_head; ++priv->tx_head; -if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size) { -ipoib_dbg (priv,"TX ring 0x%x full, stopping kernel net queue\n" , - tx->qp->qp_num); -netif_stop_queue (dev); - rc =ib_req_notify_cq (priv->send_cq, -IB_CQ_NEXT_COMP |IB_CQ_REPORT_MISSED_EVENTS ); -if (rc <0 ) -ipoib_warn (priv,"request notify on send CQ failed\n" ); -else if (rc) -ipoib_send_comp_handler (priv->send_cq, dev); - } } }
@@ -815,9 +820,10 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) ++tx->tx_tail; ++priv->tx_tail; -if (unlikely ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size >>1 ) && -netif_queue_stopped (dev) && -test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags)) + +if (unlikely (netif_queue_stopped (dev) && + (priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >>1 && +test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags)))netif_wake_queue (dev); if (wc->status != IB_WC_SUCCESS &&
@@ -1046,7 +1052,7 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_ {struct ipoib_dev_priv *priv =ipoib_priv (dev);struct ib_qp_init_attr attr = { - .send_cq = priv->recv_cq, + .send_cq = priv->send_cq, .recv_cq = priv->recv_cq, .srq = priv->cm.srq, .cap.max_send_wr = ipoib_sendq_size,
@@ -1220,9 +1226,9 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p) tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size -1 )];ipoib_dma_unmap_tx (priv, tx_req);dev_kfree_skb_any (tx_req->skb); +netif_tx_lock_bh (p->dev); ++p->tx_tail; ++priv->tx_tail; -netif_tx_lock_bh (p->dev);if (unlikely (priv->tx_head - priv->tx_tail == ipoib_sendq_size >>1 ) &&netif_queue_stopped (p->dev) &&test_bit (IPOIB_FLAG_ADMIN_UP , &priv->flags))
drivers/infiniband/ulp/ipoib/ipoib_ib.c +76 -47
223 lines not on this page · raw message
drivers/infiniband/ulp/ipoib/ipoib_main.c +19 -5
@@ -1616,13 +1616,29 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)wait_for_completion (&priv->ntbl.deleted); } +static void ipoib_napi_add (struct net_device *dev) +{ +struct ipoib_dev_priv *priv =ipoib_priv (dev); + +netif_napi_add (dev, &priv->recv_napi, ipoib_rx_poll,IPOIB_NUM_WC ); +netif_napi_add (dev, &priv->send_napi, ipoib_tx_poll,MAX_SEND_CQE ); +} + +static void ipoib_napi_del (struct net_device *dev) +{ +struct ipoib_dev_priv *priv =ipoib_priv (dev); + +netif_napi_del (&priv->recv_napi); +netif_napi_del (&priv->send_napi); +} +static void ipoib_dev_uninit_default (struct net_device *dev) {struct ipoib_dev_priv *priv =ipoib_priv (dev);ipoib_transport_dev_cleanup (dev); -netif_napi_del (&priv->napi); +ipoib_napi_del (dev);ipoib_cm_dev_cleanup (dev);
@@ -1637,7 +1653,7 @@ static int ipoib_dev_init_default(struct net_device *dev) {struct ipoib_dev_priv *priv =ipoib_priv (dev); -netif_napi_add (dev, &priv->napi, ipoib_poll,NAPI_POLL_WEIGHT ); +ipoib_napi_add (dev);/* Allocate RX/TX "rings" to hold queued skbs */ priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
@@ -1665,8 +1681,6 @@ static int ipoib_dev_init_default(struct net_device *dev) priv->dev->dev_addr[2 ] = (priv->qp->qp_num >>8 ) &0xff ; priv->dev->dev_addr[3 ] = (priv->qp->qp_num) &0xff ; -timer_setup (&priv->poll_timer, ipoib_ib_tx_timer_func,0 ); -return 0 ; out_tx_ring_cleanup:
@@ -1676,7 +1690,7 @@ static int ipoib_dev_init_default(struct net_device *dev)kfree (priv->rx_ring); out: -netif_napi_del (&priv->napi); +ipoib_napi_del (dev);return -ENOMEM ; }
drivers/infiniband/ulp/ipoib/ipoib_verbs.c +12 -5
@@ -156,7 +156,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) };struct ib_cq_init_attr cq_attr = {}; -int ret, size; +int ret, size, req_vec;int i; size = ipoib_recvq_size +1 ;
@@ -171,17 +171,21 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)if (ret != -ENOSYS )return -ENODEV ; + req_vec = (priv->port -1 ) *2 ; + cq_attr.cqe = size; - priv->recv_cq =ib_create_cq (priv->ca, ipoib_ib_completion,NULL , - dev, &cq_attr); + cq_attr.comp_vector = req_vec % priv->ca->num_comp_vectors; + priv->recv_cq =ib_create_cq (priv->ca, ipoib_ib_rx_completion,NULL , + priv, &cq_attr);if (IS_ERR (priv->recv_cq)) {printk (KERN_WARNING "%s: failed to create receive CQ\n" , ca->name); goto out_cm_dev_cleanup; } cq_attr.cqe = ipoib_sendq_size; - priv->send_cq =ib_create_cq (priv->ca, ipoib_send_comp_handler,NULL , - dev, &cq_attr); + cq_attr.comp_vector = (req_vec +1 ) % priv->ca->num_comp_vectors; + priv->send_cq =ib_create_cq (priv->ca, ipoib_ib_tx_completion,NULL , + priv, &cq_attr);if (IS_ERR (priv->send_cq)) {printk (KERN_WARNING "%s: failed to create send CQ\n" , ca->name); goto out_free_recv_cq;
@@ -208,6 +212,9 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) goto out_free_send_cq; } +if (ib_req_notify_cq (priv->send_cq,IB_CQ_NEXT_COMP )) + goto out_free_send_cq; +for (i =0 ; i <MAX_SKB_FRAGS +1 ; ++i) priv->tx_sge[i].lkey = priv->pd->local_dma_lkey;
Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/3 IB/ipoib: Change number of TX wqe to 64
In reply to a message not in the archiveFrom: Erez Shitrit <erezsh-VPRAkNaXOzVWk0Htik3J/[email protected]>
NAPI budget is 64 packets, while maximum polling size for the send CQ is 16. Let's bring them in sync, so the NAPI budget will be reused completely.
--- drivers/infiniband/ulp/ipoib/ipoib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/ulp/ipoib/ipoib.h +1 -1
@@ -111,7 +111,7 @@ enum {IPOIB_MCAST_FLAG_BUSY =2 ,IPOIB_MCAST_FLAG_ATTACHED =3 , -MAX_SEND_CQE =16 , +MAX_SEND_CQE =64 ,IPOIB_CM_COPYBREAK =256 , IPOIB_NON_CHILD = 0,
Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Doug Ledford
AppliedQuoted 26 lines · Leon Romanovsky
Changelog from v0:
* Rebase to latest for-next, commit894b82c427d0("Merge branch
'timer_setup' into for-next")----
From Erez Shitrit <erezsh-VPRAkNaXOzVWk0Htik3J/[email protected]>
----It is very common in modern network devices to use NAPI in RX and TX, in the UD/TX flows IPoIB uses a polling mechanism (not as it does in the CM mode).
Except of the motivation to use the same mechanism for IPoIB as for netdevices, there are number of issues in current polling mechanism:
* SKBs that are kept longer than they should be and there are
applications
that warn about that (some firewalls for example).
* Statistics that are not updated to the real value. It blocks
support
for time synchronization protocols over the IPoIB protocol, like
PTP
and so on.
* The TX in CM mode already uses NAPI, there is no reason to keep
two
different ways for TX one for UD and one for the CM.
Quoted 3 lines
The patches are available in the git repository at:
git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git
tags/rdma-next-2017-10-19
Thanks, applied (in lieu of the original patch set that I already replied to).
Signature · 8 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html