tcp idle reduce does not work for a server.

TCP has an idle-reduce feature that allows a connection to reduce its
cwnd after it has been idle more than an RTT. This feature only works
for a sending side connection. It does this by at output checking the
idle time (t_rcvtime vs ticks) to see if its more than the RTO timeout.

The problem comes if you are a web server. You get a request and
then send out all the data.. then go idle. The next time you would
send is in response to a request from the peer asking for more data.
But the thing is you updated t_rcvtime when the request came in so
you never reduce.

The fix is to do the idle reduce check also on inbound.

Reviewed by: tuexen, rscheff
Sponsored by: Netflix Inc
Differential Revision: https://reviews.freebsd.org/D36721
This commit is contained in:
Randall Stewart 2022-10-04 07:09:01 -04:00
parent 77198a945a
commit cd84e78f09
3 changed files with 6 additions and 3 deletions

View File

@ -1614,6 +1614,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* XXX: This should be done after segment
* validation to ignore broken/spoofed segs.
*/
if (tp->t_idle_reduce &&
(tp->snd_max == tp->snd_una) &&
((ticks - tp->t_rcvtime) >= tp->t_rxtcur))
cc_after_idle(tp);
tp->t_rcvtime = ticks;
if (thflags & TH_FIN)

View File

@ -155,8 +155,6 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto_lowat, CTLFLAG_VNET | CTLFLAG_R
tcp_timer_active((tp), TT_PERSIST), \
("neither rexmt nor persist timer is set"))
static void inline cc_after_idle(struct tcpcb *tp);
#ifdef TCP_HHOOK
/*
* Wrapper for the TCP established output helper hook.
@ -183,7 +181,7 @@ hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th,
/*
* CC wrapper hook functions
*/
static void inline
void
cc_after_idle(struct tcpcb *tp)
{
INP_WLOCK_ASSERT(tp->t_inpcb);

View File

@ -1206,6 +1206,7 @@ void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
uint32_t tcp_hc_getmtu(struct in_conninfo *);
void tcp_hc_updatemtu(struct in_conninfo *, uint32_t);
void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *);
void cc_after_idle(struct tcpcb *tp);
extern struct protosw tcp_protosw; /* shared for TOE */
extern struct protosw tcp6_protosw; /* shared for TOE */