IB/hfi1: Performance improvements for 4.16
Subsystems (2)
cover IB/hfi1: Performance improvements for 4.16
Hi Jason and Doug,
Here are a few patches that provide performance optimizations in our driver.
This is a resubmit of my previous patch set [1] broken up into smaller logically grouped patch sets.
As always my GitHub had these in-tree for context:
https://github.com/ddalessa/kernel/tree/for-4.16
[1] https://www.spinics.net/lists/linux-rdma/msg60011.html
---
Mitko Haralanov (1):
IB/hfi1: Remove dependence on qp->s_hdrwords
Sebastian Sanchez (5):
IB/hfi1: Compute BTH only for RDMA_WRITE_LAST/SEND_LAST packet IB/hfi1: Optimize packet type comparison using 9B and bypass code paths IB/hfi1: Look up ibport using a pointer in receive path IB/hfi1: Remove unnecessary fecn and becn fields
IB/hfi1: Optimize process_receive_ib()
drivers/infiniband/hw/hfi1/driver.c | 43 +++++++++++------------- drivers/infiniband/hw/hfi1/hfi.h | 18 ++++------ drivers/infiniband/hw/hfi1/iowait.h | 9 +++++ drivers/infiniband/hw/hfi1/qp.c | 4 +- drivers/infiniband/hw/hfi1/qp.h | 13 +++++++ drivers/infiniband/hw/hfi1/rc.c | 51 ++++++++++++++--------------- drivers/infiniband/hw/hfi1/ruc.c | 42 +++++++++--------------- drivers/infiniband/hw/hfi1/trace.c | 8 ++--- drivers/infiniband/hw/hfi1/trace_ibhdrs.h | 16 +++++---- drivers/infiniband/hw/hfi1/trace_rx.h | 28 ++++++---------- drivers/infiniband/hw/hfi1/uc.c | 9 +---- drivers/infiniband/hw/hfi1/ud.c | 30 +++++++---------- drivers/infiniband/hw/hfi1/verbs.c | 10 +++--- drivers/infiniband/hw/hfi1/verbs.h | 19 +++-------- drivers/infiniband/hw/hfi1/verbs_txreq.h | 7 ++++ drivers/infiniband/hw/qib/qib_rc.c | 3 +- drivers/infiniband/hw/qib/qib_uc.c | 3 +- drivers/infiniband/hw/qib/qib_ud.c | 3 +- include/rdma/ib_hdrs.h | 19 +++++++---- 19 files changed, 160 insertions(+), 175 deletions(-)
--
-Denny
--
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): 20180201184446.5918.46068.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/6 IB/hfi1: Remove dependence on qp->s_hdrwords
From: Mitko Haralanov <[email protected]>
The s_hdrwords variable was used to indicate whether a packet was already built on a previous iteration of the send engine. This variable assumed the protection of the QP's RVT_S_BUSY flag, which was required since the the QP's s_lock was dropped just prior to the packet being queued on the one of the egress mechanisms.
Support for multiple send engine instantiations require that the field not be used due to concurency issues. The ps.txreq signals the "already built" without the potential concurency issues.
Fix by getting rid of all s_hdrword usage. A wrapper
is added to test for the already built case that used to use s_hdrwords.
What used to be stored in s_hdrwords is now in the txreq. The PBC is not counted, but is added in the pio/sdma code paths prior to posting the packet.
--- drivers/infiniband/hw/hfi1/iowait.h | 9 +++++++++ drivers/infiniband/hw/hfi1/qp.c | 4 +--- drivers/infiniband/hw/hfi1/qp.h | 13 +++++++++++++ drivers/infiniband/hw/hfi1/rc.c | 10 ++-------- drivers/infiniband/hw/hfi1/ruc.c | 23 +++++++++++------------ drivers/infiniband/hw/hfi1/uc.c | 6 +----- drivers/infiniband/hw/hfi1/ud.c | 27 ++++++++++++--------------- drivers/infiniband/hw/hfi1/verbs.c | 10 +++++----- drivers/infiniband/hw/hfi1/verbs.h | 11 ----------- drivers/infiniband/hw/hfi1/verbs_txreq.h | 7 +++++++ 10 files changed, 61 insertions(+), 59 deletions(-)
drivers/infiniband/hw/hfi1/iowait.h +9 -0
@@ -371,4 +371,13 @@ static inline void iowait_starve_find_max(struct iowait *w, u8 *max, } } +/** +* iowait_packet_queued() - determine if a packet is already built +* @wait: the wait structure +*/ +static inline bool iowait_packet_queued (struct iowait *wait) +{ +return !list_empty (&wait->tx_head); +} +#endif
drivers/infiniband/hw/hfi1/qp.c +1 -3
@@ -565,7 +565,7 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)if (qp->s_ack_queue) e = &qp->s_ack_queue[qp->s_tail_ack_queue]; seq_printf(s, - "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n", + "N %d %s QP %x R %u %s %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n", iter->n, qp_idle(qp) ? "I" : "B", qp->ibqp.qp_num,
@@ -573,7 +573,6 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter) qp_type_str[qp->ibqp.qp_type], qp->state, wqe ? wqe->wr.opcode :0 , - qp->s_hdrwords, qp->s_flags,iowait_sdma_pending (&priv->s_iowait), iowait_pio_pending(&priv->s_iowait),
@@ -795,7 +794,6 @@ void notify_error_qp(struct rvt_qp *qp) }if (!(qp->s_flags &RVT_S_BUSY )) { - qp->s_hdrwords =0 ;if (qp->s_rdma_mr) {rvt_put_mr (qp->s_rdma_mr); qp->s_rdma_mr =NULL ;
drivers/infiniband/hw/hfi1/qp.h +13 -0
@@ -51,12 +51,25 @@#include <rdma/rdmavt_qp.h> #include "verbs.h" #include "sdma.h" +#include "verbs_txreq.h" extern unsigned int hfi1_qp_table_size;extern const struct rvt_operation_params hfi1_post_parms[];/* +* Send if not busy or waiting for I/O and either +* a RC response is pending or we can process send work requests. +*/ +static inline int hfi1_send_ok (struct rvt_qp *qp) +{ +return !(qp->s_flags & (RVT_S_BUSY |RVT_S_ANY_WAIT_IO )) && + (verbs_txreq_queued (qp) || + (qp->s_flags &RVT_S_RESP_PENDING ) || + !(qp->s_flags &RVT_S_ANY_WAIT_SEND )); +} + +/* * free_ahg - clear ahg from QP */ static inline void clear_ahg (struct rvt_qp *qp)
drivers/infiniband/hw/hfi1/rc.c +2 -8
@@ -226,12 +226,10 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp, bth2 =mask_psn (qp->s_ack_psn); } qp->s_rdma_ack_cnt++; - qp->s_hdrwords = hwords; ps->s_txreq->sde = priv->s_sde; ps->s_txreq->s_cur_size = len; + ps->s_txreq->hdr_dwords = hwords;hfi1_make_ruc_header (qp, ohdr, bth0, bth2, middle, ps); -/* pbc */ - ps->s_txreq->hdr_dwords = qp->s_hdrwords +2 ;return 1 ; bail:
@@ -387,7 +385,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) : IB_WC_SUCCESS);if (local_ops)atomic_dec (&qp->local_ops_pending); - qp->s_hdrwords =0 ; goto done_free_tx; }
@@ -690,7 +687,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) bth2 |=IB_BTH_REQ_ACK ; } qp->s_len -= len; - qp->s_hdrwords = hwords; + ps->s_txreq->hdr_dwords = hwords; ps->s_txreq->sde = priv->s_sde; ps->s_txreq->ss = ss; ps->s_txreq->s_cur_size = len;
@@ -701,8 +698,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) bth2, middle, ps); -/* pbc */ - ps->s_txreq->hdr_dwords = qp->s_hdrwords +2 ;return 1 ; done_free_tx:
@@ -716,7 +711,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) bail_no_tx: ps->s_txreq =NULL ; qp->s_flags &= ~RVT_S_BUSY ; - qp->s_hdrwords =0 ;return 0 ; }
drivers/infiniband/hw/hfi1/ruc.c +11 -12
@@ -757,8 +757,9 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,u32 slid;u16 pkey =hfi1_get_pkey (ibp, qp->s_pkey_index);u8 l4 =OPA_16B_L4_IB_LOCAL ; -u8 extra_bytes =hfi1_get_16b_padding ((qp->s_hdrwords <<2 ), - ps->s_txreq->s_cur_size); +u8 extra_bytes =hfi1_get_16b_padding ( + (ps->s_txreq->hdr_dwords <<2 ), + ps->s_txreq->s_cur_size);u32 nwords =SIZE_OF_CRC + ((ps->s_txreq->s_cur_size + extra_bytes +SIZE_OF_LT ) >>2 );u8 becn =0 ;
@@ -778,9 +779,9 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, grd->sgid_index =0 ; grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh; l4 =OPA_16B_L4_IB_GLOBAL ; - hdrwords = qp->s_hdrwords -4 ; - qp->s_hdrwords +=hfi1_make_grh (ibp, grh, grd, - hdrwords, nwords); + hdrwords = ps->s_txreq->hdr_dwords -4 ; + ps->s_txreq->hdr_dwords +=hfi1_make_grh (ibp, grh, grd, + hdrwords, nwords); middle =0 ; }
@@ -814,7 +815,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, slid,opa_get_lid (rdma_ah_get_dlid (&qp->remote_ah_attr),16B ), - (qp->s_hdrwords + nwords) >>1 , + (ps->s_txreq->hdr_dwords + nwords) >>1 , pkey, becn, 0, l4, priv->s_sc); }
@@ -834,10 +835,10 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,if (unlikely (rdma_ah_get_ah_flags (&qp->remote_ah_attr) &IB_AH_GRH )) {struct ib_grh *grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh; -int hdrwords = qp->s_hdrwords -2 ; +int hdrwords = ps->s_txreq->hdr_dwords -2 ; lrh0 =HFI1_LRH_GRH ; - qp->s_hdrwords += + ps->s_txreq->hdr_dwords +=hfi1_make_grh (ibp, grh,rdma_ah_read_grh (&qp->remote_ah_attr), hdrwords, nwords);
@@ -866,7 +867,7 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,hfi1_make_ruc_bth (qp, ohdr, bth0, bth1, bth2);hfi1_make_ib_hdr (&ps->s_txreq->phdr.hdr.ibh, lrh0, - qp->s_hdrwords + nwords, + ps->s_txreq->hdr_dwords + nwords,opa_get_lid (rdma_ah_get_dlid (&qp->remote_ah_attr),9B ),ppd_from_ibp (ibp)->lid |rdma_ah_get_path_bits (&qp->remote_ah_attr));
@@ -1031,7 +1032,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread) ps.s_txreq =get_waiting_verbs_txreq (qp); do { /* Check for a constructed packet to be sent. */ - if (qp->s_hdrwords != 0) { + if (ps.s_txreq) { spin_unlock_irqrestore(&qp->s_lock, ps.flags); /* * If the packet cannot be sent now, return and
@@ -1039,8 +1040,6 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)*/ if (hfi1_verbs_send (qp, &ps))return ; -/* Record that s_ahg is empty. */ - qp->s_hdrwords =0 ;/* allow other tasks to run */ if (schedule_send_yield (qp, &ps))return ;
drivers/infiniband/hw/hfi1/uc.c +1 -5
@@ -146,7 +146,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) : IB_WC_SUCCESS);if (local_ops)atomic_dec (&qp->local_ops_pending); - qp->s_hdrwords =0 ; goto done_free_tx; }/*
@@ -269,14 +268,12 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)break ; } qp->s_len -= len; - qp->s_hdrwords = hwords; + ps->s_txreq->hdr_dwords = hwords; ps->s_txreq->sde = priv->s_sde; ps->s_txreq->ss = &qp->s_sge; ps->s_txreq->s_cur_size = len;hfi1_make_ruc_header (qp, ohdr, bth0 | (qp->s_state <<24 ),mask_psn (qp->s_psn++), middle, ps); -/* pbc */ - ps->s_txreq->hdr_dwords = qp->s_hdrwords +2 ;return 1 ; done_free_tx:
@@ -290,7 +287,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) bail_no_tx: ps->s_txreq =NULL ; qp->s_flags &= ~RVT_S_BUSY ; - qp->s_hdrwords =0 ;return 0 ; }
drivers/infiniband/hw/hfi1/ud.c +12 -15
@@ -340,15 +340,15 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps, extra_bytes = -wqe->length &3 ; nwords = ((wqe->length + extra_bytes) >>2 ) +SIZE_OF_CRC ;/* header size in dwords LRH+BTH+DETH = (8+12+8)/4. */ - qp->s_hdrwords =7 ; + ps->s_txreq->hdr_dwords =7 ;if (wqe->wr.opcode ==IB_WR_SEND_WITH_IMM ) - qp->s_hdrwords++; + ps->s_txreq->hdr_dwords++;if (rdma_ah_get_ah_flags (ah_attr) &IB_AH_GRH ) { grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh; - qp->s_hdrwords +=hfi1_make_grh (ibp, grh, -rdma_ah_read_grh (ah_attr), - qp->s_hdrwords -2 , nwords); + ps->s_txreq->hdr_dwords += +hfi1_make_grh (ibp, grh,rdma_ah_read_grh (ah_attr), + ps->s_txreq->hdr_dwords -2 , nwords); lrh0 =HFI1_LRH_GRH ; ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth; }else {
@@ -381,7 +381,7 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps, } }hfi1_make_bth_deth (qp, wqe, ohdr, &pkey, extra_bytes, false); - len = qp->s_hdrwords + nwords; + len = ps->s_txreq->hdr_dwords + nwords;/* Setup the packet */ ps->s_txreq->phdr.hdr.hdr_type =HFI1_PKT_TYPE_9B ;
@@ -405,12 +405,12 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps, ppd =ppd_from_ibp (ibp); ah_attr = &ibah_to_rvtah (wqe->ud_wr.ah)->attr;/* header size in dwords 16B LRH+BTH+DETH = (16+12+8)/4. */ - qp->s_hdrwords =9 ; + ps->s_txreq->hdr_dwords =9 ;if (wqe->wr.opcode ==IB_WR_SEND_WITH_IMM ) - qp->s_hdrwords++; + ps->s_txreq->hdr_dwords++;/* SW provides space for CRC and LT for bypass packets. */ - extra_bytes =hfi1_get_16b_padding ((qp->s_hdrwords <<2 ), + extra_bytes =hfi1_get_16b_padding ((ps->s_txreq->hdr_dwords <<2 ), wqe->length); nwords = ((wqe->length + extra_bytes +SIZE_OF_LT ) >>2 ) +SIZE_OF_CRC ;
@@ -428,8 +428,8 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps, grd->sgid_index =0 ; } grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh; - qp->s_hdrwords +=hfi1_make_grh (ibp, grh, grd, - qp->s_hdrwords -4 , nwords); + ps->s_txreq->hdr_dwords +=hfi1_make_grh (ibp, grh, grd, + ps->s_txreq->hdr_dwords -4 , nwords); ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth; l4 =OPA_16B_L4_IB_GLOBAL ; }else {
@@ -452,7 +452,7 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,hfi1_make_bth_deth (qp, wqe, ohdr, &pkey, extra_bytes, true);/* Convert dwords to flits */ - len = (qp->s_hdrwords + nwords) >>1 ; + len = (ps->s_txreq->hdr_dwords + nwords) >>1 ;/* Setup the packet */ ps->s_txreq->phdr.hdr.hdr_type =HFI1_PKT_TYPE_16B ;
@@ -564,8 +564,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) priv->s_ahg->ahgcount =0 ; priv->s_ahg->ahgidx =0 ; priv->s_ahg->tx_flags =0 ; -/* pbc */ - ps->s_txreq->hdr_dwords = qp->s_hdrwords +2 ;return 1 ;
@@ -580,7 +578,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) bail_no_tx: ps->s_txreq =NULL ; qp->s_flags &= ~RVT_S_BUSY ; - qp->s_hdrwords =0 ;return 0 ; }
drivers/infiniband/hw/hfi1/verbs.c +5 -5
@@ -835,7 +835,7 @@ static int build_verbs_tx_desc( {int ret =0 ;struct hfi1_sdma_header *phdr = &tx->phdr; -u16 hdrbytes = tx->hdr_dwords <<2 ; +u16 hdrbytes = (tx->hdr_dwords +sizeof (pbc) /4 ) <<2 ;u8 extra_bytes =0 ;if (tx->phdr.hdr.hdr_type) {
@@ -901,7 +901,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps, {struct hfi1_qp_priv *priv = qp->priv;struct hfi1_ahg_info *ahg_info = priv->s_ahg; -u32 hdrwords = qp->s_hdrwords; +u32 hdrwords = ps->s_txreq->hdr_dwords;u32 len = ps->s_txreq->s_cur_size;u32 plen;struct hfi1_ibdev *dev = ps->dev;
@@ -919,7 +919,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps, }else { dwords = (len +3 ) >>2 ; } - plen = hdrwords + dwords +2 ; + plen = hdrwords + dwords +sizeof (pbc) /4 ; tx = ps->s_txreq;if (!sdma_txreq_built (&tx->txreq)) {
@@ -1038,7 +1038,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps, u64 pbc) {struct hfi1_qp_priv *priv = qp->priv; -u32 hdrwords = qp->s_hdrwords; +u32 hdrwords = ps->s_txreq->hdr_dwords;struct rvt_sge_state *ss = ps->s_txreq->ss;u32 len = ps->s_txreq->s_cur_size;u32 dwords;
@@ -1064,7 +1064,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps, dwords = (len +3 ) >>2 ; hdr = (u32 *)&ps->s_txreq->phdr.hdr.ibh; } - plen = hdrwords + dwords +2 ; + plen = hdrwords + dwords +sizeof (pbc) /4 ;/* only RC/UC use complete */ switch (qp->ibqp.qp_type) {
drivers/infiniband/hw/hfi1/verbs.h +0 -11
@@ -246,17 +246,6 @@ struct hfi1_ibdev { }/* -* Send if not busy or waiting for I/O and either -* a RC response is pending or we can process send work requests. -*/ -static inline int hfi1_send_ok (struct rvt_qp *qp) -{ -return !(qp->s_flags & (RVT_S_BUSY |RVT_S_ANY_WAIT_IO )) && - (qp->s_hdrwords || (qp->s_flags &RVT_S_RESP_PENDING ) || - !(qp->s_flags &RVT_S_ANY_WAIT_SEND )); -} - -/* * This must be called with s_lock held. */ void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
drivers/infiniband/hw/hfi1/verbs_txreq.h +7 -0
@@ -113,6 +113,13 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,return NULL ; } +static inline bool verbs_txreq_queued (struct rvt_qp *qp) +{ +struct hfi1_qp_priv *priv = qp->priv; + +return iowait_packet_queued (&priv->s_iowait); +} +void hfi1_put_txreq (struct verbs_txreq *tx);int verbs_txreq_init (struct hfi1_ibdev *dev);void verbs_txreq_exit (struct hfi1_ibdev *dev);
--
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/6 IB/hfi1: Compute BTH only for RDMA_WRITE_LAST/SEND_LAST packet
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
In hfi1_rc_rcv(), BTH is computed for all packets received. However, it's only used for packets received with opcodes RDMA_WRITE_LAST and SEND_LAST, and it is a costly operation.
Compute BTH only in the RDMA_WRITE_LAST/SEND_LAST code path and let the compiler handle endianness conversion for bitwise operations.
--- drivers/infiniband/hw/hfi1/rc.c | 3 +-- drivers/infiniband/hw/hfi1/uc.c | 3 +-- drivers/infiniband/hw/hfi1/ud.c | 3 +-- drivers/infiniband/hw/qib/qib_rc.c | 3 +-- drivers/infiniband/hw/qib/qib_uc.c | 3 +-- drivers/infiniband/hw/qib/qib_ud.c | 3 +-- include/rdma/ib_hdrs.h | 4 ++++ 7 files changed, 10 insertions(+), 12 deletions(-)
drivers/infiniband/hw/hfi1/rc.c +1 -2
@@ -2035,7 +2035,6 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)struct rvt_qp *qp = packet->qp;struct hfi1_ibport *ibp =rcd_to_iport (rcd);struct ib_other_headers *ohdr = packet->ohdr; -u32 bth0 =be32_to_cpu (ohdr->bth[0 ]);u32 opcode = packet->opcode;u32 hdrsize = packet->hlen;u32 psn =ib_bth_get_psn (packet->ohdr);
@@ -2233,7 +2232,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) wc.port_num =0 ;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (bth0 &IB_BTH_SOLICITED ) !=0 ); +ib_bth_is_solicited (ohdr));break ;case OP (RDMA_WRITE_ONLY ):
drivers/infiniband/hw/hfi1/uc.c +1 -2
@@ -478,8 +478,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet) wc.port_num =0 ;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (ohdr->bth[0 ] & -cpu_to_be32 (IB_BTH_SOLICITED )) !=0 ); +ib_bth_is_solicited (ohdr));break ;case OP (RDMA_WRITE_FIRST ):
drivers/infiniband/hw/hfi1/ud.c +1 -2
@@ -1045,8 +1045,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet) wc.port_num = qp->port_num;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (ohdr->bth[0 ] & -cpu_to_be32 (IB_BTH_SOLICITED )) !=0 ); +ib_bth_is_solicited (ohdr));return ; drop:
drivers/infiniband/hw/qib/qib_rc.c +1 -2
@@ -1916,8 +1916,7 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr, wc.port_num =0 ;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (ohdr->bth[0 ] & -cpu_to_be32 (IB_BTH_SOLICITED )) !=0 ); +ib_bth_is_solicited (ohdr));break ;case OP (RDMA_WRITE_FIRST ):
drivers/infiniband/hw/qib/qib_uc.c +1 -2
@@ -403,8 +403,7 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct ib_header *hdr, wc.port_num =0 ;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (ohdr->bth[0 ] & -cpu_to_be32 (IB_BTH_SOLICITED )) !=0 ); +ib_bth_is_solicited (ohdr));break ;case OP (RDMA_WRITE_FIRST ):
drivers/infiniband/hw/qib/qib_ud.c +1 -2
@@ -581,8 +581,7 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr, wc.port_num = qp->port_num;/* Signal completion event if the solicited bit is set. */ rvt_cq_enter (ibcq_to_rvtcq (qp->ibqp.recv_cq), &wc, - (ohdr->bth[0 ] & -cpu_to_be32 (IB_BTH_SOLICITED )) !=0 ); +ib_bth_is_solicited (ohdr));return ; drop:
include/rdma/ib_hdrs.h +4 -0
@@ -331,4 +331,8 @@ static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr) IB_BTH_TVER_MASK); } +static inline bool ib_bth_is_solicited (struct ib_other_headers *ohdr) +{ +return !!(ohdr->bth[0 ] &cpu_to_be32 (IB_BTH_SOLICITED )); +}#endif /* IB_HDRS_H */
--
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/6 IB/hfi1: Optimize packet type comparison using 9B and bypass code paths
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
The packet type comparison used to find out if a packet is a bypass packet in the hot path is an expensive operation as seen in a profile.
Determine packet's pkey and migration bit through the bypass and 9B code paths instead.
--- drivers/infiniband/hw/hfi1/driver.c | 4 ++++ drivers/infiniband/hw/hfi1/hfi.h | 2 ++ drivers/infiniband/hw/hfi1/ruc.c | 15 ++------------- drivers/infiniband/hw/hfi1/verbs.h | 5 +++++ include/rdma/ib_hdrs.h | 5 +++++ 5 files changed, 18 insertions(+), 13 deletions(-)
drivers/infiniband/hw/hfi1/driver.c +4 -0
@@ -1440,6 +1440,8 @@ static int hfi1_setup_9B_packet(struct hfi1_packet *packet) packet->extra_byte =0 ; packet->fecn =ib_bth_get_fecn (packet->ohdr); packet->becn =ib_bth_get_becn (packet->ohdr); + packet->pkey =ib_bth_get_pkey (packet->ohdr); + packet->migrated =ib_bth_is_migration (packet->ohdr);return 0 ; drop:
@@ -1506,6 +1508,8 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet) packet->extra_byte =SIZE_OF_LT ; packet->fecn =hfi1_16B_get_fecn (packet->hdr); packet->becn =hfi1_16B_get_becn (packet->hdr); + packet->pkey =hfi1_16B_get_pkey (packet->hdr); + packet->migrated =opa_bth_is_migration (packet->ohdr);if (hfi1_bypass_ingress_pkt_check (packet)) goto drop;
drivers/infiniband/hw/hfi1/hfi.h +2 -0
@@ -341,6 +341,7 @@ struct hfi1_packet {u32 slid;u16 tlen;s16 etail; +u16 pkey;u8 hlen;u8 numpkt;u8 rsize;
@@ -353,6 +354,7 @@ struct hfi1_packet {u8 opcode;bool becn;bool fecn; +bool migrated; };/* Packet types */
drivers/infiniband/hw/hfi1/ruc.c +2 -13
@@ -225,19 +225,8 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet)u32 dlid = packet->dlid;u32 slid = packet->slid;u32 sl = packet->sl; -int migrated; -u32 bth0, bth1; -u16 pkey; - - bth0 =be32_to_cpu (packet->ohdr->bth[0 ]); - bth1 =be32_to_cpu (packet->ohdr->bth[1 ]); -if (packet->etype ==RHF_RCV_TYPE_BYPASS ) { - pkey =hfi1_16B_get_pkey (packet->hdr); - migrated = bth1 &OPA_BTH_MIG_REQ ; - }else { - pkey =ib_bth_get_pkey (packet->ohdr); - migrated = bth0 &IB_BTH_MIG_REQ ; - } +bool migrated = packet->migrated; +u16 pkey = packet->pkey;if (qp->s_mig_state ==IB_MIG_ARMED && migrated) {if (!packet->grh) {
drivers/infiniband/hw/hfi1/verbs.h +5 -0
@@ -405,6 +405,11 @@ static inline void cacheless_memcpy(void *dst, void *src, size_t n)__copy_user_nocache (dst, (void __user *)src, n,0 ); } +static inline bool opa_bth_is_migration (struct ib_other_headers *ohdr) +{ +return !!(ohdr->bth[1 ] &cpu_to_be32 (OPA_BTH_MIG_REQ )); +} +extern const enum ib_wc_opcode ib_hfi1_wc_opcode[];extern const u8 hdr_len_by_opcode[];
include/rdma/ib_hdrs.h +5 -0
@@ -335,4 +335,9 @@ static inline bool ib_bth_is_solicited(struct ib_other_headers *ohdr) {return !!(ohdr->bth[0 ] &cpu_to_be32 (IB_BTH_SOLICITED )); } + +static inline bool ib_bth_is_migration (struct ib_other_headers *ohdr) +{ +return !!(ohdr->bth[0 ] &cpu_to_be32 (IB_BTH_MIG_REQ )); +}#endif /* IB_HDRS_H */
--
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): 20180201184620.5918.82548.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
Re: [PATCH for-next 3/6] IB/hfi1: Optimize packet type comparison using 9B and bypass code paths
Quoted 13 lines · Dennis Dalessandro
drivers/infiniband/hw/hfi1/verbs.h +5
-0+static inline bool opa_bth_is_migration (struct ib_other_headers *ohdr) +{ +return !!(ohdr->bth[1 ] &cpu_to_be32 (OPA_BTH_MIG_REQ )); +} +extern const enum ib_wc_opcode ib_hfi1_wc_opcode[];extern const u8 hdr_len_by_opcode[];include/rdma/ib_hdrs.h +1
-0+++ b/include/rdma/ib_hdrs.h
include/rdma/ib_hdrs.h static inline bool ib_bth_is_solicited(struct ib_other_headers *ohdr) · line 343
Quoted 9 lines
include/rdma/ib_hdrs.h +5
-0@@ -335,4 +335,9 @@ static inline bool ib_bth_is_solicited(struct ib_other_headers *ohdr) {return !!(ohdr->bth[0 ] &cpu_to_be32 (IB_BTH_SOLICITED )); } + +static inline bool ib_bth_is_migration (struct ib_other_headers *ohdr) +{ +return !!(ohdr->bth[0 ] &cpu_to_be32 (IB_BTH_MIG_REQ )); +}#endif /* IB_HDRS_H */
No on the !! - the cast to 'bool' causes the compiler to do this automatically and is clearer. This is why we have 'bool'
I fixed the patch for you, please send another patch to get rid of the other !! in boolean contexts I saw in this code.
Jason
--
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 4/6 IB/hfi1: Look up ibport using a pointer in receive path
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
In the receive path, hfi1_ibport is looked up by indexing into an array. A profile shows this to be expensive. The receive context data has a pointer to the ibport data, use that pointer instead.
--- drivers/infiniband/hw/hfi1/driver.c | 14 ++++++++------ drivers/infiniband/hw/hfi1/rc.c | 36 ++++++++++++++++++++--------------- drivers/infiniband/hw/hfi1/verbs.h | 3 +-- 3 files changed, 30 insertions(+), 23 deletions(-)
drivers/infiniband/hw/hfi1/driver.c +8 -6
@@ -634,9 +634,10 @@ static void __prescan_rxq(struct hfi1_packet *packet) } } -static void process_rcv_qp_work (struct hfi1_ctxtdata *rcd) +static void process_rcv_qp_work (struct hfi1_packet *packet) {struct rvt_qp *qp, *nqp; +struct hfi1_ctxtdata *rcd = packet->rcd;/* * Iterate over all QPs waiting to respond.
@@ -646,7 +647,8 @@ static void process_rcv_qp_work(struct hfi1_ctxtdata *rcd)list_del_init (&qp->rspwait);if (qp->r_flags &RVT_R_RSP_NAK ) { qp->r_flags &= ~RVT_R_RSP_NAK ; -hfi1_send_rc_ack (rcd, qp,0 ); + packet->qp = qp; +hfi1_send_rc_ack (packet,0 ); }if (qp->r_flags &RVT_R_RSP_SEND ) {unsigned long flags;
@@ -667,7 +669,7 @@ static noinline int max_packet_exceeded(struct hfi1_packet *packet, int thread)if (thread) {if ((packet->numpkt & (MAX_PKT_RECV_THREAD -1 )) ==0 )/* allow defered processing */ -process_rcv_qp_work (packet->rcd); +process_rcv_qp_work (packet);cond_resched ();return RCV_PKT_OK ; }else {
@@ -809,7 +811,7 @@ int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread) last =RCV_PKT_DONE ;process_rcv_update (last, &packet); } -process_rcv_qp_work (rcd); +process_rcv_qp_work (&packet); rcd->head = packet.rhqoff; bail:finish_packet (&packet);
@@ -838,7 +840,7 @@ int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread) last =RCV_PKT_DONE ;process_rcv_update (last, &packet); } -process_rcv_qp_work (rcd); +process_rcv_qp_work (&packet); rcd->head = packet.rhqoff; bail:finish_packet (&packet);
@@ -1068,7 +1070,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)process_rcv_update (last, &packet); } -process_rcv_qp_work (rcd); +process_rcv_qp_work (&packet); rcd->head = packet.rhqoff; bail:
drivers/infiniband/hw/hfi1/rc.c +21 -15
@@ -730,14 +730,16 @@ static inline void hfi1_make_bth_aeth(struct rvt_qp *qp, ohdr->bth[2 ] =cpu_to_be32 (mask_psn (qp->r_ack_psn)); } -static inline void hfi1_queue_rc_ack (struct rvt_qp *qp,bool is_fecn) +static inline void hfi1_queue_rc_ack (struct hfi1_packet *packet,bool is_fecn) { -struct hfi1_ibport *ibp =to_iport (qp->ibqp.device, qp->port_num); +struct rvt_qp *qp = packet->qp; +struct hfi1_ibport *ibp;unsigned long flags;spin_lock_irqsave (&qp->s_lock, flags);if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_RECV_OK )) goto unlock; + ibp =rcd_to_iport (packet->rcd);this_cpu_inc (*ibp->rvp.rc_qacks); qp->s_flags |=RVT_S_ACK_PENDING |RVT_S_RESP_PENDING ; qp->s_nak_state = qp->r_nak_state;
@@ -751,13 +753,14 @@ static inline void hfi1_queue_rc_ack(struct rvt_qp *qp, bool is_fecn)spin_unlock_irqrestore (&qp->s_lock, flags); } -static inline void hfi1_make_rc_ack_9B (struct rvt_qp *qp, +static inline void hfi1_make_rc_ack_9B (struct hfi1_packet *packet,struct hfi1_opa_header *opa_hdr,u8 sc5,bool is_fecn,u64 *pbc_flags,u32 *hwords,u32 *nwords) { -struct hfi1_ibport *ibp =to_iport (qp->ibqp.device, qp->port_num); +struct rvt_qp *qp = packet->qp; +struct hfi1_ibport *ibp =rcd_to_iport (packet->rcd);struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);struct ib_header *hdr = &opa_hdr->ibh;struct ib_other_headers *ohdr;
@@ -798,13 +801,14 @@ static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,hfi1_make_bth_aeth (qp, ohdr, bth0, bth1); } -static inline void hfi1_make_rc_ack_16B (struct rvt_qp *qp, +static inline void hfi1_make_rc_ack_16B (struct hfi1_packet *packet,struct hfi1_opa_header *opa_hdr,u8 sc5,bool is_fecn,u64 *pbc_flags,u32 *hwords,u32 *nwords) { -struct hfi1_ibport *ibp =to_iport (qp->ibqp.device, qp->port_num); +struct rvt_qp *qp = packet->qp; +struct hfi1_ibport *ibp =rcd_to_iport (packet->rcd);struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);struct hfi1_16b_header *hdr = &opa_hdr->opah;struct ib_other_headers *ohdr;
@@ -850,7 +854,7 @@ static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,hfi1_make_bth_aeth (qp, ohdr, bth0, bth1); } -typedef void (*hfi1_make_rc_ack)(struct rvt_qp *qp, +typedef void (*hfi1_make_rc_ack)(struct hfi1_packet *packet, struct hfi1_opa_header *opa_hdr, u8 sc5, bool is_fecn, u64 *pbc_flags, u32 *hwords,
@@ -870,9 +874,10 @@ typedef void (*hfi1_make_rc_ack)(struct rvt_qp *qp,* Note that RDMA reads and atomics are handled in the * send side QP state and send engine. */ -void hfi1_send_rc_ack (struct hfi1_ctxtdata *rcd, -struct rvt_qp *qp,bool is_fecn) +void hfi1_send_rc_ack (struct hfi1_packet *packet,bool is_fecn) { +struct hfi1_ctxtdata *rcd = packet->rcd; +struct rvt_qp *qp = packet->qp;struct hfi1_ibport *ibp =rcd_to_iport (rcd);struct hfi1_qp_priv *priv = qp->priv;struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);
@@ -889,14 +894,14 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,/* Don't send ACK or NAK if a RDMA read or atomic is pending. */ if (qp->s_flags &RVT_S_RESP_PENDING ) { -hfi1_queue_rc_ack (qp, is_fecn); +hfi1_queue_rc_ack (packet, is_fecn);return ; }/* Ensure s_rdma_ack_cnt changes are committed */ smp_read_barrier_depends ();if (qp->s_rdma_ack_cnt) { -hfi1_queue_rc_ack (qp, is_fecn); +hfi1_queue_rc_ack (packet, is_fecn);return ; }
@@ -905,7 +910,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,return ;/* Make the appropriate header */ - hfi1_make_rc_ack_tbl[priv->hdr_type](qp, &opa_hdr, sc5, is_fecn, + hfi1_make_rc_ack_tbl[priv->hdr_type](packet, &opa_hdr, sc5, is_fecn, &pbc_flags, &hwords, &nwords); plen =2 /* PBC */ + hwords + nwords;
@@ -919,7 +924,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,* so that when enough buffer space becomes available, * the ACK is sent ahead of other outgoing packets. */ -hfi1_queue_rc_ack (qp, is_fecn); +hfi1_queue_rc_ack (packet, is_fecn);return ; } trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
@@ -1537,7 +1542,7 @@ static void rc_rcv_resp(struct hfi1_packet *packet)void *data = packet->payload;u32 tlen = packet->tlen;struct rvt_qp *qp = packet->qp; -struct hfi1_ibport *ibp =to_iport (qp->ibqp.device, qp->port_num); +struct hfi1_ibport *ibp;struct ib_other_headers *ohdr = packet->ohdr;struct rvt_swqe *wqe;enum ib_wc_status status;
@@ -1695,6 +1700,7 @@ static void rc_rcv_resp(struct hfi1_packet *packet) goto ack_err; ack_seq_err: + ibp =rcd_to_iport (rcd);rdma_seq_err (qp, ibp, psn, rcd); goto ack_done;
@@ -2476,7 +2482,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) qp->r_nak_state =IB_NAK_REMOTE_ACCESS_ERROR ; qp->r_ack_psn = qp->r_psn; send_ack: -hfi1_send_rc_ack (rcd, qp, is_fecn); +hfi1_send_rc_ack (packet, is_fecn); } void hfi1_rc_hdrerr(
drivers/infiniband/hw/hfi1/verbs.h +1 -2
@@ -358,8 +358,7 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr,void hfi1_send_complete (struct rvt_qp *qp,struct rvt_swqe *wqe,enum ib_wc_status status); -void hfi1_send_rc_ack (struct hfi1_ctxtdata *rcd,struct rvt_qp *qp, -bool is_fecn); +void hfi1_send_rc_ack (struct hfi1_packet *packet,bool is_fecn);int hfi1_make_rc_req (struct rvt_qp *qp,struct hfi1_pkt_state *ps);
--
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 5/6 IB/hfi1: Remove unnecessary fecn and becn fields
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
packet->fecn and packet->becn are calculated in the hot path and are never used. Remove these fields as they show to be costly in a profile. Also, remove initialization for becn and fecn in process_ecn() as they're unconditionally assigned in the function and ensure fecn and becn variables use a boolean type.
--- drivers/infiniband/hw/hfi1/driver.c | 4 ---- drivers/infiniband/hw/hfi1/hfi.h | 16 +++++----------- drivers/infiniband/hw/hfi1/rc.c | 2 +- drivers/infiniband/hw/hfi1/ruc.c | 4 ++-- drivers/infiniband/hw/hfi1/trace.c | 8 ++++---- drivers/infiniband/hw/hfi1/trace_ibhdrs.h | 16 ++++++++-------- include/rdma/ib_hdrs.h | 10 ++++------ 7 files changed, 24 insertions(+), 36 deletions(-)
drivers/infiniband/hw/hfi1/driver.c +0 -4
@@ -1440,8 +1440,6 @@ static int hfi1_setup_9B_packet(struct hfi1_packet *packet) packet->sc =hfi1_9B_get_sc5 (hdr, packet->rhf); packet->pad =ib_bth_get_pad (packet->ohdr); packet->extra_byte =0 ; - packet->fecn =ib_bth_get_fecn (packet->ohdr); - packet->becn =ib_bth_get_becn (packet->ohdr); packet->pkey =ib_bth_get_pkey (packet->ohdr); packet->migrated =ib_bth_is_migration (packet->ohdr);
@@ -1508,8 +1506,6 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet) packet->sl = ibp->sc_to_sl[packet->sc]; packet->pad =hfi1_16B_bth_get_pad (packet->ohdr); packet->extra_byte =SIZE_OF_LT ; - packet->fecn =hfi1_16B_get_fecn (packet->hdr); - packet->becn =hfi1_16B_get_becn (packet->hdr); packet->pkey =hfi1_16B_get_pkey (packet->hdr); packet->migrated =opa_bth_is_migration (packet->ohdr);
drivers/infiniband/hw/hfi1/hfi.h +5 -11
@@ -352,8 +352,6 @@ struct hfi1_packet {u8 sc;u8 sl;u8 opcode; -bool becn; -bool fecn;bool migrated; };
@@ -1781,19 +1779,15 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,static inline bool process_ecn (struct rvt_qp *qp,struct hfi1_packet *pkt,bool do_cnp) { -struct ib_other_headers *ohdr = pkt->ohdr; - -u32 bth1; -bool becn = false; -bool fecn = false; +bool becn; +bool fecn;if (pkt->etype ==RHF_RCV_TYPE_BYPASS ) { fecn =hfi1_16B_get_fecn (pkt->hdr); becn =hfi1_16B_get_becn (pkt->hdr); }else { - bth1 =be32_to_cpu (ohdr->bth[1 ]); - fecn = bth1 &IB_FECN_SMASK ; - becn = bth1 &IB_BECN_SMASK ; + fecn =ib_bth_get_fecn (pkt->ohdr); + becn =ib_bth_get_becn (pkt->ohdr); }if (unlikely (fecn || becn)) {hfi1_process_ecn_slowpath (qp, pkt, do_cnp);
@@ -2419,7 +2413,7 @@ static inline void hfi1_make_ib_hdr(struct ib_header *hdr,static inline void hfi1_make_16b_hdr (struct hfi1_16b_header *hdr,u32 slid,u32 dlid,u16 len,u16 pkey, -u8 becn,u8 fecn,u8 l4, +bool becn,bool fecn,u8 l4,u8 sc) {u32 lrh0 =0 ;
drivers/infiniband/hw/hfi1/rc.c +1 -1
@@ -814,7 +814,7 @@ static inline void hfi1_make_rc_ack_16B(struct hfi1_packet *packet,struct ib_other_headers *ohdr;u32 bth0, bth1 =0 ;u16 len, pkey; -u8 becn = !!is_fecn; +bool becn = is_fecn;u8 l4 =OPA_16B_L4_IB_LOCAL ;u8 extra_bytes;
drivers/infiniband/hw/hfi1/ruc.c +2 -2
@@ -751,7 +751,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, ps->s_txreq->s_cur_size);u32 nwords =SIZE_OF_CRC + ((ps->s_txreq->s_cur_size + extra_bytes +SIZE_OF_LT ) >>2 ); -u8 becn =0 ; +bool becn = false;if (unlikely (rdma_ah_get_ah_flags (&qp->remote_ah_attr) &IB_AH_GRH ) &&hfi1_check_mcast (rdma_ah_get_dlid (&qp->remote_ah_attr))) {
@@ -789,7 +789,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,if (qp->s_flags &RVT_S_ECN ) { qp->s_flags &= ~RVT_S_ECN ;/* we recently received a FECN, so return a BECN */ - becn =1 ; + becn = true; }hfi1_make_ruc_bth (qp, ohdr, bth0, bth1, bth2);
drivers/infiniband/hw/hfi1/trace.c +4 -4
@@ -138,7 +138,7 @@ u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opa_hdr) }void hfi1_trace_parse_9b_bth (struct ib_other_headers *ohdr, -u8 *ack,u8 *becn,u8 *fecn,u8 *mig, +u8 *ack,bool *becn,bool *fecn,u8 *mig,u8 *se,u8 *pad,u8 *opcode,u8 *tver,u16 *pkey,u32 *psn,u32 *qpn) {
@@ -184,7 +184,7 @@ void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5, }void hfi1_trace_parse_16b_hdr (struct hfi1_16b_header *hdr, -u8 *age,u8 *becn,u8 *fecn, +u8 *age,bool *becn,bool *fecn,u8 *l4,u8 *rc,u8 *sc,u16 *entropy,u16 *len,u16 *pkey,u32 *dlid,u32 *slid)
@@ -207,7 +207,7 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,#define LRH_16B_PRN "age:%d becn:%d fecn:%d l4:%d " \ "rc:%d sc:%d pkey:0x%.4x entropy:0x%.4x"const char *hfi1_trace_fmt_lrh (struct trace_seq *p,bool bypass, -u8 age,u8 becn,u8 fecn,u8 l4, +u8 age,bool becn,bool fecn,u8 l4,u8 lnh,const char *lnh_name,u8 lver,u8 rc,u8 sc,u8 sl,u16 entropy,u16 len,u16 pkey,u32 dlid,u32 slid)
@@ -235,7 +235,7 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,"op:0x%.2x,%s se:%d m:%d pad:%d tver:%d " \"qpn:0x%.6x a:%d psn:0x%.8x" const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass, - u8 ack, u8 becn, u8 fecn, u8 mig, + u8 ack, bool becn, bool fecn, u8 mig, u8 se, u8 pad, u8 opcode, const char *opname, u8 tver, u16 pkey, u32 psn, u32 qpn) {
drivers/infiniband/hw/hfi1/trace_ibhdrs.h +8 -8
@@ -101,7 +101,7 @@u8 hfi1_trace_packet_hdr_len (struct hfi1_packet *packet);const char *hfi1_trace_get_packet_l4_str (u8 l4);void hfi1_trace_parse_9b_bth (struct ib_other_headers *ohdr, -u8 *ack,u8 *becn,u8 *fecn,u8 *mig, +u8 *ack,bool *becn,bool *fecn,u8 *mig,u8 *se,u8 *pad,u8 *opcode,u8 *tver,u16 *pkey,u32 *psn,u32 *qpn); void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
@@ -112,19 +112,19 @@ void hfi1_trace_parse_16b_bth(struct ib_other_headers *ohdr, u8 *pad, u8 *se, u8 *tver, u32 *psn, u32 *qpn);void hfi1_trace_parse_16b_hdr (struct hfi1_16b_header *hdr, -u8 *age,u8 *becn,u8 *fecn, +u8 *age,bool *becn,bool *fecn,u8 *l4,u8 *rc,u8 *sc,u16 *entropy,u16 *len,u16 *pkey,u32 *dlid,u32 *slid);const char *hfi1_trace_fmt_lrh (struct trace_seq *p,bool bypass, -u8 age,u8 becn,u8 fecn,u8 l4, +u8 age,bool becn,bool fecn,u8 l4,u8 lnh,const char *lnh_name,u8 lver,u8 rc,u8 sc,u8 sl,u16 entropy,u16 len,u16 pkey,u32 dlid,u32 slid);const char *hfi1_trace_fmt_bth (struct trace_seq *p,bool bypass, -u8 ack,u8 becn,u8 fecn,u8 mig, +u8 ack,bool becn,bool fecn,u8 mig,u8 se,u8 pad,u8 opcode,const char *opname,u8 tver,u16 pkey,u32 psn,u32 qpn);
@@ -148,8 +148,8 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr, __field(u8, etype) __field(u8, ack) __field(u8, age) - __field(u8, becn) - __field(u8, fecn) + __field(bool, becn) + __field(bool, fecn) __field(u8, l2) __field(u8, l4)__field (u8, lnh)
@@ -290,8 +290,8 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr, __field(u8, hdr_type) __field(u8, ack) __field(u8, age) - __field(u8, becn) - __field(u8, fecn) + __field(bool, becn) + __field(bool, fecn) __field(u8, l4) __field(u8, lnh)__field (u8, lver)
include/rdma/ib_hdrs.h +4 -6
@@ -313,16 +313,14 @@ static inline u32 ib_bth_get_qpn(struct ib_other_headers *ohdr)return (u32)((be32_to_cpu (ohdr->bth[1 ])) &IB_QPN_MASK ); } -static inline u8 ib_bth_get_becn (struct ib_other_headers *ohdr) +static inline bool ib_bth_get_becn (struct ib_other_headers *ohdr) { -return (u8)((be32_to_cpu (ohdr->bth[1 ]) >>IB_BECN_SHIFT ) & -IB_BECN_MASK ); +return !!((ohdr->bth[1 ]) &cpu_to_be32 (IB_BECN_SMASK )); } -static inline u8 ib_bth_get_fecn (struct ib_other_headers *ohdr) +static inline bool ib_bth_get_fecn (struct ib_other_headers *ohdr) { -return (u8)((be32_to_cpu (ohdr->bth[1 ]) >>IB_FECN_SHIFT ) & -IB_FECN_MASK ); +return !!((ohdr->bth[1 ]) &cpu_to_be32 (IB_FECN_SMASK )); }static inline u8 ib_bth_get_tver (struct ib_other_headers *ohdr)
--
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 6/6 IB/hfi1: Optimize process_receive_ib()
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
The arguments for trace_hfi1_rcvhdr() get computed every time in the hot path regardless of the whether the trace is on or off. This is seen to be costly with a profile. The handling of fault inject isolates the verbs device for all packets regardless of the presence of a RHF_DC_ERR error.
Fix the first by computing trace_hfi1_rcvhdr() arguments within the trace itself, so that when the trace is off, the argument data isn't computed. Fix the second by moving the error check to handle_eflags() when an RHF error occurs and by testing for RHF_DC_ERR before executing the reset of handle_eflags().
--- drivers/infiniband/hw/hfi1/driver.c | 21 +++++++-------------- drivers/infiniband/hw/hfi1/trace_rx.h | 28 ++++++++++------------------ 2 files changed, 17 insertions(+), 32 deletions(-)
drivers/infiniband/hw/hfi1/driver.c +7 -14
@@ -256,7 +256,12 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,u32 mlid_base;struct hfi1_ibport *ibp =rcd_to_iport (rcd);struct hfi1_devdata *dd = ppd->dd; -struct rvt_dev_info *rdi = &dd->verbs_dev.rdi; +struct hfi1_ibdev *verbs_dev = &dd->verbs_dev; +struct rvt_dev_info *rdi = &verbs_dev->rdi; + +if ((packet->rhf &RHF_DC_ERR ) && +hfi1_dbg_fault_suppress_err (verbs_dev)) +return ;if (packet->rhf & (RHF_VCRC_ERR |RHF_ICRC_ERR ))return ;
@@ -1552,19 +1557,7 @@ int process_receive_ib(struct hfi1_packet *packet)if (hfi1_setup_9B_packet (packet))return RHF_RCV_CONTINUE ; -trace_hfi1_rcvhdr (packet->rcd->ppd->dd, - packet->rcd->ctxt, -rhf_err_flags (packet->rhf), -RHF_RCV_TYPE_IB , - packet->hlen, - packet->tlen, - packet->updegr, -rhf_egr_index (packet->rhf)); - -if (unlikely ( - (hfi1_dbg_fault_suppress_err (&packet->rcd->dd->verbs_dev) && - (packet->rhf &RHF_DC_ERR )))) -return RHF_RCV_CONTINUE ; +trace_hfi1_rcvhdr (packet,RHF_RCV_TYPE_IB );if (unlikely (rhf_err_flags (packet->rhf))) {handle_eflags (packet);
drivers/infiniband/hw/hfi1/trace_rx.h +10 -18
@@ -63,17 +63,9 @@#define TRACE_SYSTEM hfi1_rx TRACE_EVENT(hfi1_rcvhdr, - TP_PROTO(struct hfi1_devdata *dd, - u32 ctxt, - u64 eflags, - u32 etype, - u32 hlen, - u32 tlen, - u32 updegr, - u32 etail - ), - TP_ARGS(dd, ctxt, eflags, etype, hlen, tlen, updegr, etail), - TP_STRUCT__entry(DD_DEV_ENTRY(dd) + TP_PROTO(struct hfi1_packet *packet, u32 etype), + TP_ARGS(packet, etype), + TP_STRUCT__entry(DD_DEV_ENTRY(packet->rcd->dd) __field(u64, eflags) __field(u32, ctxt) __field(u32, etype)
@@ -82,14 +74,14 @@ __field(u32, updegr)__field (u32, etail) ), - TP_fast_assign(DD_DEV_ASSIGN(dd); - __entry->eflags = eflags; - __entry->ctxt = ctxt; + TP_fast_assign(DD_DEV_ASSIGN(packet->rcd->dd); + __entry->eflags =rhf_err_flags (packet->rhf); + __entry->ctxt = packet->rcd->ctxt; __entry->etype = etype; - __entry->hlen = hlen; - __entry->tlen = tlen; - __entry->updegr = updegr; - __entry->etail = etail; + __entry->hlen = packet->hlen; + __entry->tlen = packet->tlen; + __entry->updegr = packet->updegr; + __entry->etail =rhf_egr_index (packet->rhf); ), TP_printk( "[%s] ctxt %d eflags 0x%llx etype %d,%s hlen %d tlen %d updegr %d etail %d",
--
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
Jason Gunthorpe
AppliedQuoted 14 lines · Dennis Dalessandro
Hi Jason and Doug,
Here are a few patches that provide performance optimizations in our driver.
This is a resubmit of my previous patch set [1] broken up into smaller logically grouped patch sets.
As always my GitHub had these in-tree for context:
https://github.com/ddalessa/kernel/tree/for-4.16[1] https://www.spinics.net/lists/linux-rdma/msg60011.html
Mitko Haralanov (1):
Quoted 8 lines
IB/hfi1: Remove dependence on qp->s_hdrwordsSebastian Sanchez (5):
IB/hfi1: Compute BTH only for RDMA_WRITE_LAST/SEND_LAST packet IB/hfi1: Optimize packet type comparison using 9B and bypass code paths IB/hfi1: Look up ibport using a pointer in receive path IB/hfi1: Remove unnecessary fecn and becn fields
IB/hfi1: Optimizeprocess_receive_ib()
Applied to for-next, thanks
Jason
--
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