diff options
author | Mike Marciniszyn <mike.marciniszyn@intel.com> | 2015-11-10 09:14:01 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-19 16:58:18 -0800 |
commit | 7c091e5c0685c463dc58e5115781f7ac0a1448d6 (patch) | |
tree | 28ad8ba2a9087a36e998684768e1cb6c08536b3e /drivers/staging/rdma/hfi1/rc.c | |
parent | staging/rdma/hfi1: add common routine for queuing acks (diff) | |
download | linux-dev-7c091e5c0685c463dc58e5115781f7ac0a1448d6.tar.xz linux-dev-7c091e5c0685c463dc58e5115781f7ac0a1448d6.zip |
staging/rdma/hfi1: add ACK coalescing logic
Implement ACK coalesing logic using a 8 bit counter.
The algorithm is send pio ack when:
- fecn present
- this is the first packet in an interrupt session
- counter is >= HFI1_PSN_CREDIT
Otherwise the ack is defered.
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/rdma/hfi1/rc.c')
-rw-r--r-- | drivers/staging/rdma/hfi1/rc.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/staging/rdma/hfi1/rc.c b/drivers/staging/rdma/hfi1/rc.c index 0c10012cc397..6f4a155f7931 100644 --- a/drivers/staging/rdma/hfi1/rc.c +++ b/drivers/staging/rdma/hfi1/rc.c @@ -1618,6 +1618,17 @@ static inline void rc_defered_ack(struct hfi1_ctxtdata *rcd, } } +static inline void rc_cancel_ack(struct hfi1_qp *qp) +{ + qp->r_adefered = 0; + if (list_empty(&qp->rspwait)) + return; + list_del_init(&qp->rspwait); + qp->r_flags &= ~HFI1_R_RSP_DEFERED_ACK; + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); +} + /** * rc_rcv_error - process an incoming duplicate or error RC packet * @ohdr: the other headers for this packet @@ -2335,8 +2346,22 @@ send_last: qp->r_ack_psn = psn; qp->r_nak_state = 0; /* Send an ACK if requested or required. */ - if (psn & (1 << 31)) - goto send_ack; + if (psn & IB_BTH_REQ_ACK) { + if (packet->numpkt == 0) { + rc_cancel_ack(qp); + goto send_ack; + } + if (qp->r_adefered >= HFI1_PSN_CREDIT) { + rc_cancel_ack(qp); + goto send_ack; + } + if (unlikely(is_fecn)) { + rc_cancel_ack(qp); + goto send_ack; + } + qp->r_adefered++; + rc_defered_ack(rcd, qp); + } return; rnr_nak: |