Linux – Real-World Use of TCP_DEFER_ACCEPT

linuxnetworkingtcpwebserver

I was perusing the Apache httpd manual online and came across a directive for enabling this. Found a description in the man page for tcp:

   TCP_DEFER_ACCEPT (since Linux 2.4)
          Allow a listener to be awakened only when data arrives on the
          socket.  Takes an integer value (seconds), this can bound the
          maximum number of attempts TCP will make to complete the
          connection.  This option should not be used in code intended
          to be portable.

Then I found this article but I'm still unclear what kind of workloads this would be useful for. I'm assuming that if httpd has an option specifically for this, it must have some relevance to web servers. I'm also assuming from the fact it's an option and not just how httpd does network connections, that there are use cases where you want it and others where you don't.

Even after reading the article, I'm unclear on what the advantage to waiting for the three way handshake to complete would be. It would seem advantageous to ensure it's not going to need to swap-in the relevant httpd instance by doing so while the handshake is still going on instead of potentially causing that delay after a connection is formed.

For the article, it would also seem to me that no matter the TCP_DEFER_ACCEPT status of a socket, you're still going to need four packets (handshake then data in each case). I don't know how they get the count down to three, nor how that provides a meaningful enhancement.

So my question is basically: Is this just an old obsolete option or is there an actual use case for this option?

Best Answer

(to summarise my comments on the OP)

The three-way handshake that they are refering to is part of the TCP connection establishment, the option in question doesn't relate specifically to this. Also note that data exchange is not part of the three way handshake, this just creates the TCP connection in the open/established state.

Regarding the existance of this option, this is not the traditional behaviour of a socket, normally the socket handler's thread is woken up when the connection is accepted (which is still after the three way handshake completes), and for some protocols activity starts here (e.g. an SMTP server sends a 220 greeting line), but for HTTP the first message in the conversation is the web browser sending its GET/POST/etc line, and until this happens the HTTP server has no interest in the connection (other than timing it out), thus waking up the HTTP process when the socket accept completes is a wasteful activity as the process will immediately fall asleep again waiting for the necessary data.

While there is certainly argument that waking up idle processes can make them 'ready' for further processing (I specifically remember waking up login terminals on very old machines and having them chug in from swap), but you can also argue that any machine that has swapped out said process is already making demands on its resources, and making further unnecessary demands might overall reduce system performance - even if your individual thread's apparent performance improves (which it also may not, an extremely busy machine would have bottlenecks on disk IO which would slow other things down if you swapped in, and if its that busy, the immediate sleep might swap it right back out). It seems to be a gamble, and ultimately the 'greedy' gamble doesn't necessarily pay off on a busy machine, and certainly causes extra unnecessary work on a machine that already had the process swapped in - your approach optimises for a machine with a large memory set of processes that are mostly dormant, and swapping one dormancy for another is no big deal, however a machine with a large memory set of active processes will suffer from extra IO, and any machine that isn't memory limited, suffers, any CPU bound machine will be worse off.

My general advice regarding that level of performance tuning would be to not make programatic decisions about what is best anyway, but to allow the system administrator and operating system to work together to deal with the resource management issues - that is their job and they are much better suited to understanding the workloads of the entire system and beyond. Give options and configuration choices.

To specifically answer the question, the option is beneficial on all configurations, not to the level you'd ever likely notice except under an extreme load of HTTP traffic, but it's theoretically the "right" way to do it. It's an option because not all Unix (not even all Linux) flavours have that capability, and thus for portability it can be configured not to be inclided.

Related Question