From: Simon Wilkinson Date: Wed, 12 Oct 2011 13:47:14 +0000 (-0400) Subject: rx: Don't clear the receive queue when out of packets X-Git-Tag: upstream/1.6.1.pre1^2~129 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=4ff4ec8ac94a75385d919f9031abaec31aca9b26;p=packages%2Fo%2Fopenafs.git rx: Don't clear the receive queue when out of packets We can end up discarding a receive queue that's been soft acked, effectively taking back soft acks we sent. Whilst the RX documentation says that a client can drop soft acked packets at will, our RX implementation assumes that if the final packet in a call has been soft acked, we won't clear the queue. If a client clears the queue in this situation, the call will hang. What *should* happen is that we should take necessary locks, confirm that we have not soft-acked all of the packets in a flow, and then discard, or, if we're just going to discard, error the call. Reviewed-on: http://gerrit.openafs.org/5603 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry-picked from f722a75fe21963d64217375f1f7bbb0eb14befb4) Change-Id: Ie2f14a0ed7b6d258a7f456387df44ac95fd1748c Reviewed-on: http://gerrit.openafs.org/5820 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/rx/rx.c b/src/rx/rx.c index bb42e75fc..4245b1849 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -3853,8 +3853,9 @@ rxi_ReceiveDataPacket(struct rx_call *call, call->rprev = np->header.serial; rxi_calltrace(RX_TRACE_DROP, call); dpf(("packet %"AFS_PTR_FMT" dropped on receipt - quota problems", np)); - if (rxi_doreclaim) - rxi_ClearReceiveQueue(call); + /* We used to clear the receive queue here, in an attempt to free + * packets. However this is unsafe if the queue has received a + * soft ACK for the final packet */ clock_GetTime(&now); when = now; clock_Add(&when, &rx_softAckDelay); diff --git a/src/rx/rx_globals.h b/src/rx/rx_globals.h index c4c829964..7723d61a8 100644 --- a/src/rx/rx_globals.h +++ b/src/rx/rx_globals.h @@ -483,7 +483,6 @@ EXT osi_socket rx_minSocketNumber GLOBALSINIT(0x7fffffff); #define RX_MAX_QUOTA 15 /* part of min packet computation */ EXT int rx_packetQuota[RX_N_PACKET_CLASSES] GLOBALSINIT(RX_PACKET_QUOTAS); EXT int meltdown_1pkt GLOBALSINIT(1); /* prefer to schedule single-packet calls */ -EXT int rxi_doreclaim GLOBALSINIT(1); /* if discard one packet, discard all */ EXT int rxi_md2cnt GLOBALSINIT(0); /* counter of skipped calls */ EXT int rxi_2dchoice GLOBALSINIT(1); /* keep track of another call to schedule */