Page MenuHomeFreeBSD

tcp idle reduce does not work for a server.
ClosedPublic

Authored by rrs on Sep 26 2022, 5:39 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Apr 22, 5:30 AM
Unknown Object (File)
Mon, Apr 22, 5:30 AM
Unknown Object (File)
Mon, Apr 22, 5:30 AM
Unknown Object (File)
Mon, Apr 22, 5:16 AM
Unknown Object (File)
Dec 20 2023, 6:12 AM
Unknown Object (File)
Dec 10 2023, 8:58 PM
Unknown Object (File)
Nov 25 2023, 4:03 PM
Unknown Object (File)
Nov 11 2023, 2:06 PM

Details

Summary

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.

Test Plan

This is easy to test with a server setup. All you need to do
is send in a request, let it complete, have the app go idle
and then send in a subsequent request (with idle reduce enabled
of course). If you do it in that sequence you should see the cwnd
fall.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

rrs requested review of this revision.Sep 26 2022, 5:39 PM

I have a vage recollection, of something along these lines having been checked in "recently" (within last 2 years?)

Ah, here - https://reviews.freebsd.org/D25016

was that incomplete, or not implemented properly?

It shouldn't matter that much if we reduce cwnd right at the receipt of a new segment (in tcp_input), or just prior of sending out the next segment (in tcp_output)?

I have a vage recollection, of something along these lines having been checked in "recently" (within last 2 years?)

Ah, here - https://reviews.freebsd.org/D25016

was that incomplete, or not implemented properly?

It shouldn't matter that much if we reduce cwnd right at the receipt of a new segment (in tcp_input), or just prior of sending out the next segment (in tcp_output)?

Richard:

The problem is that the previous "fix" did not fix the issue. Imagine being a server (think http). You
get a request (like NF does) and you send some chunk of data.... your done your cwnd is now 1,000,000.
Now you sit idle by waiting. The client sends you the next chunk request (or another HTTP request if
your not streaming video). Now what happens, you update t_rcvtime, you just got a segment right?

Now you have been idle the whole time.. and now you send (in response to the request). Guess what
t_rcvtime was updated so you *do not* lower the cwnd like you should..

If you just send data (without getting a request) you would have lowered your cwnd.

So this fixes a broken-ness that has been there for a *very* long time. D25016 only
fixed 1/2 the issue. It never fixed the problem where the server waits for a request
and then sends data.

This revision is now accepted and ready to land.Oct 3 2022, 11:21 AM
This revision was automatically updated to reflect the committed changes.