aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rdma/hfi1/rc.c
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2015-11-10 09:14:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-19 16:58:18 -0800
commit7c091e5c0685c463dc58e5115781f7ac0a1448d6 (patch)
tree28ad8ba2a9087a36e998684768e1cb6c08536b3e /drivers/staging/rdma/hfi1/rc.c
parentstaging/rdma/hfi1: add common routine for queuing acks (diff)
downloadlinux-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.c29
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: