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 <shadow@dementix.org>
Tested-by: Derrick Brashear <shadow@dementix.org>
(cherry-picked from
f722a75fe21963d64217375f1f7bbb0eb14befb4)
Change-Id: Ie2f14a0ed7b6d258a7f456387df44ac95fd1748c
Reviewed-on: http://gerrit.openafs.org/5820
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
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);
#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 */