rxrpc: Add re-sent Tx annotation
authorDavid Howells <dhowells@redhat.com>
Wed, 21 Sep 2016 23:29:32 +0000 (00:29 +0100)
committerDavid Howells <dhowells@redhat.com>
Thu, 22 Sep 2016 00:23:50 +0000 (01:23 +0100)
Add a Tx-phase annotation for packet buffers to indicate that a buffer has
already been retransmitted.  This will be used by future congestion
management.  Re-retransmissions of a packet don't affect the congestion
window managment in the same way as initial retransmissions.

Signed-off-by: David Howells <dhowells@redhat.com>
net/rxrpc/ar-internal.h
net/rxrpc/call_event.c
net/rxrpc/input.c

index f021df4a6a22da7ede989b73b52801b58c7f853e..dcf54e3fb478c491b459bc35ecf737bfc47cee83 100644 (file)
@@ -505,6 +505,8 @@ struct rxrpc_call {
 #define RXRPC_TX_ANNO_UNACK    1
 #define RXRPC_TX_ANNO_NAK      2
 #define RXRPC_TX_ANNO_RETRANS  3
+#define RXRPC_TX_ANNO_MASK     0x03
+#define RXRPC_TX_ANNO_RESENT   0x04
 #define RXRPC_RX_ANNO_JUMBO    0x3f            /* Jumbo subpacket number + 1 if not zero */
 #define RXRPC_RX_ANNO_JLAST    0x40            /* Set if last element of a jumbo packet */
 #define RXRPC_RX_ANNO_VERIFIED 0x80            /* Set if verified and decrypted */
index 6247ce25eb216ae9e7d9459b22ba28fa227f2620..34ad967f2d818e259a82cb5ee1335a843737dc48 100644 (file)
@@ -144,7 +144,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
        rxrpc_seq_t cursor, seq, top;
        unsigned long resend_at, now;
        int ix;
-       u8 annotation;
+       u8 annotation, anno_type;
 
        _enter("{%d,%d}", call->tx_hard_ack, call->tx_top);
 
@@ -165,14 +165,16 @@ static void rxrpc_resend(struct rxrpc_call *call)
        for (seq = cursor + 1; before_eq(seq, top); seq++) {
                ix = seq & RXRPC_RXTX_BUFF_MASK;
                annotation = call->rxtx_annotations[ix];
-               if (annotation == RXRPC_TX_ANNO_ACK)
+               anno_type = annotation & RXRPC_TX_ANNO_MASK;
+               annotation &= ~RXRPC_TX_ANNO_MASK;
+               if (anno_type == RXRPC_TX_ANNO_ACK)
                        continue;
 
                skb = call->rxtx_buffer[ix];
                rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
                sp = rxrpc_skb(skb);
 
-               if (annotation == RXRPC_TX_ANNO_UNACK) {
+               if (anno_type == RXRPC_TX_ANNO_UNACK) {
                        if (time_after(sp->resend_at, now)) {
                                if (time_before(sp->resend_at, resend_at))
                                        resend_at = sp->resend_at;
@@ -181,7 +183,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
                }
 
                /* Okay, we need to retransmit a packet. */
-               call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS;
+               call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS | annotation;
        }
 
        call->resend_at = resend_at;
@@ -194,7 +196,8 @@ static void rxrpc_resend(struct rxrpc_call *call)
        for (seq = cursor + 1; before_eq(seq, top); seq++) {
                ix = seq & RXRPC_RXTX_BUFF_MASK;
                annotation = call->rxtx_annotations[ix];
-               if (annotation != RXRPC_TX_ANNO_RETRANS)
+               anno_type = annotation & RXRPC_TX_ANNO_MASK;
+               if (anno_type != RXRPC_TX_ANNO_RETRANS)
                        continue;
 
                skb = call->rxtx_buffer[ix];
@@ -220,10 +223,17 @@ static void rxrpc_resend(struct rxrpc_call *call)
                 * received and the packet might have been hard-ACK'd (in which
                 * case it will no longer be in the buffer).
                 */
-               if (after(seq, call->tx_hard_ack) &&
-                   (call->rxtx_annotations[ix] == RXRPC_TX_ANNO_RETRANS ||
-                    call->rxtx_annotations[ix] == RXRPC_TX_ANNO_NAK))
-                       call->rxtx_annotations[ix] = RXRPC_TX_ANNO_UNACK;
+               if (after(seq, call->tx_hard_ack)) {
+                       annotation = call->rxtx_annotations[ix];
+                       anno_type = annotation & RXRPC_TX_ANNO_MASK;
+                       if (anno_type == RXRPC_TX_ANNO_RETRANS ||
+                           anno_type == RXRPC_TX_ANNO_NAK) {
+                               annotation &= ~RXRPC_TX_ANNO_MASK;
+                               annotation |= RXRPC_TX_ANNO_UNACK;
+                       }
+                       annotation |= RXRPC_TX_ANNO_RESENT;
+                       call->rxtx_annotations[ix] = annotation;
+               }
 
                if (after(call->tx_hard_ack, seq))
                        seq = call->tx_hard_ack;
index 7ac1edf3aac70f0da2c0ab9745e77371e476e1eb..aa261df9fc9e62e203a4cc0b1f13e33c5e23abe8 100644 (file)
@@ -388,17 +388,25 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
 {
        bool resend = false;
        int ix;
+       u8 annotation, anno_type;
 
        for (; nr_acks > 0; nr_acks--, seq++) {
                ix = seq & RXRPC_RXTX_BUFF_MASK;
+               annotation = call->rxtx_annotations[ix];
+               anno_type = annotation & RXRPC_TX_ANNO_MASK;
+               annotation &= ~RXRPC_TX_ANNO_MASK;
                switch (*acks++) {
                case RXRPC_ACK_TYPE_ACK:
-                       call->rxtx_annotations[ix] = RXRPC_TX_ANNO_ACK;
+                       if (anno_type == RXRPC_TX_ANNO_ACK)
+                               continue;
+                       call->rxtx_annotations[ix] =
+                               RXRPC_TX_ANNO_ACK | annotation;
                        break;
                case RXRPC_ACK_TYPE_NACK:
-                       if (call->rxtx_annotations[ix] == RXRPC_TX_ANNO_NAK)
+                       if (anno_type == RXRPC_TX_ANNO_NAK)
                                continue;
-                       call->rxtx_annotations[ix] = RXRPC_TX_ANNO_NAK;
+                       call->rxtx_annotations[ix] =
+                               RXRPC_TX_ANNO_NAK | annotation;
                        resend = true;
                        break;
                default: