TCP: make after-idle work for transactional sessions.

The use of t_rcvtime as proxy for the last transmission
fails for transactional IO, where the client requests
data before the server can respond with a bulk transfer.

Set aside a dedicated variable to actually track the last
locally sent segment going forward.

Reported by:	rrs
Reviewed by:	rrs, tuexen (mentor)
Approved by:	tuexen (mentor), rgrimes (mentor)
MFC after:	2 weeks
Sponsored by:	NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D25016
This commit is contained in:
Richard Scheffenegger 2020-06-24 13:42:42 +00:00
parent 2d143336de
commit 9dc7d8a246
2 changed files with 6 additions and 3 deletions

View File

@ -260,7 +260,8 @@ tcp_output(struct tcpcb *tp)
* to send, then transmit; otherwise, investigate further.
*/
idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una);
if (idle && ticks - tp->t_rcvtime >= tp->t_rxtcur)
if (idle && (((ticks - tp->t_rcvtime) >= tp->t_rxtcur) ||
(tp->t_sndtime && ((ticks - tp->t_sndtime) >= tp->t_rxtcur))))
cc_after_idle(tp);
tp->t_flags &= ~TF_LASTIDLE;
if (idle) {
@ -1502,6 +1503,7 @@ tcp_output(struct tcpcb *tp)
* Time this transmission if not a retransmission and
* not currently timing anything.
*/
tp->t_sndtime = ticks;
if (tp->t_rtttime == 0) {
tp->t_rtttime = ticks;
tp->t_rtseq = startseq;

View File

@ -188,8 +188,9 @@ struct tcpcb {
tcp_seq snd_wl2; /* window update seg ack number */
tcp_seq irs; /* initial receive sequence number */
tcp_seq iss; /* initial send sequence number */
u_int t_acktime;
tcp_seq iss; /* initial send sequence number */
u_int t_acktime; /* RACK and BBR incoming new data was acked */
u_int t_sndtime; /* time last data was sent */
u_int ts_recent_age; /* when last updated */
tcp_seq snd_recover; /* for use in NewReno Fast Recovery */
uint16_t cl4_spare; /* Spare to adjust CL 4 */