staging/rdma/hfi1: add ACK coalescing logic
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Tue, 10 Nov 2015 14:14:01 +0000 (09:14 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Nov 2015 00:58:18 +0000 (16:58 -0800)
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>
drivers/staging/rdma/hfi1/qp.c
drivers/staging/rdma/hfi1/rc.c
drivers/staging/rdma/hfi1/verbs.h

index d37c4a77d1d87dee1f58c5ae89e6fe25b7f4572f..ce036810d57617337812d25af707ec5bca980e2d 100644 (file)
@@ -378,6 +378,7 @@ static void reset_qp(struct hfi1_qp *qp, enum ib_qp_type type)
        }
        qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
        qp->r_nak_state = 0;
+       qp->r_adefered = 0;
        qp->r_aflags = 0;
        qp->r_flags = 0;
        qp->s_head = 0;
index 0c10012cc397f0425979bf936f22f442f38ae10e..6f4a155f793195b12b91bad637e4dffdfb2af1b8 100644 (file)
@@ -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:
index 6a49a3ca96b457bbd445a751893f645ac53f4102..cdc844f56c6b11f0b734259ac81ea76ed3867938 100644 (file)
@@ -120,9 +120,9 @@ struct hfi1_packet;
 
 #define HFI1_VENDOR_IPG                cpu_to_be16(0xFFA0)
 
-#define IB_BTH_REQ_ACK         (1 << 31)
-#define IB_BTH_SOLICITED       (1 << 23)
-#define IB_BTH_MIG_REQ         (1 << 22)
+#define IB_BTH_REQ_ACK         BIT(31)
+#define IB_BTH_SOLICITED       BIT(23)
+#define IB_BTH_MIG_REQ         BIT(22)
 
 #define IB_GRH_VERSION         6
 #define IB_GRH_VERSION_MASK    0xF
@@ -490,6 +490,7 @@ struct hfi1_qp {
        u32 r_psn;              /* expected rcv packet sequence number */
        u32 r_msn;              /* message sequence number */
 
+       u8 r_adefered;         /* number of acks defered */
        u8 r_state;             /* opcode of last packet received */
        u8 r_flags;
        u8 r_head_ack_queue;    /* index into s_ack_queue[] */