From: Nickolai Zeldovich Date: Thu, 14 Nov 2002 21:38:41 +0000 (+0000) Subject: Slight change to the semantics of the serial number field in the X-Git-Tag: openafs-stable-1_2_8~43 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=3a6c957ee626f7a63d58469cf1aea2fbc7f2232a;p=packages%2Fo%2Fopenafs.git Slight change to the semantics of the serial number field in the ack packet, which results in more reliable RTT computation. (cherry picked from commit 70872e9d3cba906a28fa4cf78a080819c822f5f6) --- diff --git a/src/rx/rx.c b/src/rx/rx.c index d6b182e8f..dba5ddd7c 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -2782,8 +2782,11 @@ struct rx_packet *rxi_ReceivePacket(np, socket, host, port, tnop, newcallp) /* Respond immediately to ack packets requesting acknowledgement * (ping packets) */ if (np->header.flags & RX_REQUEST_ACK) { - if (call->error) (void) rxi_SendCallAbort(call, 0, 1, 0); - else (void) rxi_SendAck(call, 0, 0, 0, 0, RX_ACK_PING_RESPONSE, 1); + if (call->error) + (void) rxi_SendCallAbort(call, 0, 1, 0); + else + (void) rxi_SendAck(call, 0, 0, np->header.serial, 0, + RX_ACK_PING_RESPONSE, 1); } np = rxi_ReceiveAckPacket(call, np, 1); break; @@ -3382,6 +3385,27 @@ static void rxi_UpdatePeerReach(conn, acall) MUTEX_EXIT(&conn->conn_data_lock); } +/* rxi_ComputePeerNetStats + * + * Called exclusively by rxi_ReceiveAckPacket to compute network link + * estimates (like RTT and throughput) based on ack packets. Caller + * must ensure that the packet in question is the right one (i.e. + * serial number matches). + */ +static void +rxi_ComputePeerNetStats(struct rx_call *call, struct rx_packet *p, + struct rx_ackPacket *ap, struct rx_packet *np) +{ + struct rx_peer *peer = call->conn->peer; + + /* Use RTT if not delayed by client. */ + if (ap->reason != RX_ACK_DELAY) + rxi_ComputeRoundTripTime(p, &p->timeSent, peer); +#ifdef ADAPT_WINDOW + rxi_ComputeRate(peer, call, p, np, ap->reason); +#endif +} + /* The real smarts of the whole thing. */ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack) register struct rx_call *call; @@ -3449,15 +3473,6 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack) } #endif - /* if a server connection has been re-created, it doesn't remember what - serial # it was up to. An ack will tell us, since the serial field - contains the largest serial received by the other side */ - MUTEX_ENTER(&conn->conn_data_lock); - if ((conn->type == RX_SERVER_CONNECTION) && (conn->serial < serial)) { - conn->serial = serial+1; - } - MUTEX_EXIT(&conn->conn_data_lock); - /* Update the outgoing packet skew value to the latest value of * the peer's incoming packet skew value. The ack packet, of * course, could arrive out of order, but that won't affect things @@ -3473,22 +3488,9 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack) for (queue_Scan(&call->tq, tp, nxp, rx_packet)) { if (tp->header.seq >= first) break; call->tfirst = tp->header.seq + 1; - if (tp->header.serial == serial) { - /* 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) { - /* 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 - } + if (serial && (tp->header.serial == serial || + tp->firstSerial == serial)) + rxi_ComputePeerNetStats(call, tp, ap, np); #ifdef AFS_GLOBAL_RXLOCK_KERNEL /* XXX Hack. Because we have to release the global rx lock when sending * packets (osi_NetSend) we drop all acks while we're traversing the tq @@ -3541,30 +3543,12 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack) * of this packet */ #ifdef AFS_GLOBAL_RXLOCK_KERNEL #ifdef RX_ENABLE_LOCKS - if (tp->header.seq >= first) { -#endif /* RX_ENABLE_LOCKS */ -#endif /* AFS_GLOBAL_RXLOCK_KERNEL */ - if (tp->header.serial == serial) { - /* 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)) { - /* 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 - } -#ifdef AFS_GLOBAL_RXLOCK_KERNEL -#ifdef RX_ENABLE_LOCKS - } + if (tp->header.seq >= first) #endif /* RX_ENABLE_LOCKS */ #endif /* AFS_GLOBAL_RXLOCK_KERNEL */ + if (serial && (tp->header.serial == serial || + tp->firstSerial == serial)) + rxi_ComputePeerNetStats(call, tp, ap, np); /* Set the acknowledge flag per packet based on the * information in the ack packet. An acknowlegded packet can @@ -4573,7 +4557,7 @@ struct rx_packet *rxi_SendAck(call, optionalPacket, seq, serial, pflags, reason, /* The skew computation used to be bogus, I think it's better now. */ /* We should start paying attention to skew. XXX */ - ap->serial = htonl(call->conn->maxSerial); + ap->serial = htonl(serial); ap->maxSkew = 0; /* used to be peer->inPacketSkew */ ap->firstPacket = htonl(call->rnext); /* First packet not yet forwarded to reader */