fix-rx-rtt-computation-when-delay-is-involved-20010326
authorNickolai Zeldovich <kolya@mit.edu>
Tue, 27 Mar 2001 01:51:35 +0000 (01:51 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 27 Mar 2001 01:51:35 +0000 (01:51 +0000)
"   rx: attempt to fix incorrect rtt computation, possibly winning
    on performance for links with some packet loss.

    Currently, the rtt is computed as the time from the transmission
    of a packet until the receipt of the corresponding ack packet.
    But this includes a potential delay (rx_{soft,hard,last}AckDelay)
    on the client which results in an abnormally high rtt, and even
    more erroneous rtt_dev and retransmit timeout values.

    The proposed solution is to ignore RX_ACK_DELAY type ack packets
    for the purposes of rtt computations, and introduce another ack
    packet type for RX_ACK_DELAY-type acks which are sent immediately
    by the client.

    This should of course be backwards-compatible with existing clients.
"

src/rx/rx.c
src/rx/rx.h

index 14b47af..7af02f3 100644 (file)
@@ -3151,7 +3151,7 @@ nextloop:;
     } else if (call->nSoftAcks > (u_short)rxi_SoftAckRate) {
        rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
        np = rxi_SendAck(call, np, seq, serial, flags,
-                        RX_ACK_DELAY, istack);
+                        RX_ACK_IDLE, istack);
     } else if (call->nSoftAcks) {
        clock_GetTime(&when);
        if (haveLast && !(flags & RX_CLIENT_INITIATED)) {
@@ -3267,13 +3267,17 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
        if (tp->header.seq >= first) break;
        call->tfirst = tp->header.seq + 1;
        if (tp->header.serial == serial) {
-         rxi_ComputeRoundTripTime(tp, &tp->timeSent, peer);
+         /* Use RTT if not delayed by client. */
+         if (ap->reason != RX_ACK_DELAY)
+             rxi_ComputeRoundTripTime(tp, &tp->timeSent, peer);
 #ifdef ADAPT_WINDOW
          rxi_ComputeRate(peer, call, tp, np, ap->reason);
 #endif
        }
-       else if ((tp->firstSerial == serial)) {
-         rxi_ComputeRoundTripTime(tp, &tp->firstSent, peer);
+       else if (tp->firstSerial == serial) {
+           /* Use RTT if not delayed by client. */
+           if (ap->reason != RX_ACK_DELAY)
+               rxi_ComputeRoundTripTime(tp, &tp->firstSent, peer);
 #ifdef ADAPT_WINDOW
          rxi_ComputeRate(peer, call, tp, np, ap->reason);
 #endif
@@ -3334,13 +3338,17 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
 #endif /* RX_ENABLE_LOCKS */
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
        if (tp->header.serial == serial) {
-         rxi_ComputeRoundTripTime(tp, &tp->timeSent, peer);
+           /* Use RTT if not delayed by client. */
+           if (ap->reason != RX_ACK_DELAY)
+               rxi_ComputeRoundTripTime(tp, &tp->timeSent, peer);
 #ifdef ADAPT_WINDOW
          rxi_ComputeRate(peer, call, tp, np, ap->reason);
 #endif
        }
        else if ((tp->firstSerial == serial)) {
-         rxi_ComputeRoundTripTime(tp, &tp->firstSent, peer);
+           /* Use RTT if not delayed by client. */
+           if (ap->reason != RX_ACK_DELAY)
+               rxi_ComputeRoundTripTime(tp, &tp->firstSent, peer);
 #ifdef ADAPT_WINDOW
          rxi_ComputeRate(peer, call, tp, np, ap->reason);
 #endif
@@ -3820,7 +3828,7 @@ register struct rx_call **newcallp;
        if (call->flags & RX_CALL_CLEARED) {
            /* send an ack now to start the packet flow up again */
            call->flags &= ~RX_CALL_CLEARED;
-           rxi_SendAck(call, 0, 0, 0, 0, RX_ACK_DELAY, 0);
+           rxi_SendAck(call, 0, 0, 0, 0, RX_ACK_IDLE, 0);
        }
 #ifdef RX_ENABLE_LOCKS
        CV_SIGNAL(&sq->cv);
index 9f7d24b..7820cb0 100644 (file)
@@ -690,6 +690,8 @@ struct rx_ackPacket {
 #define        RX_ACK_PING             6   /* This is a keep-alive ack */
 #define        RX_ACK_PING_RESPONSE    7   /* Ack'ing because we were pinged */
 #define        RX_ACK_DELAY            8   /* Ack generated since nothing has happened since receiving packet */
+#define RX_ACK_IDLE             9   /* Similar to RX_ACK_DELAY, but can 
+                                             be */
 
 /* Packet acknowledgement type */ 
 #define        RX_ACK_TYPE_NACK        0   /* I Don't have this packet */