tcp_input()'s DELAY_ACK() code checks to see if the delayed ack timer is
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 3 Aug 2004 00:04:13 +0000 (00:04 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 3 Aug 2004 00:04:13 +0000 (00:04 +0000)
commit2b1ce38a26291667d9ed98c77d898c34e1aae541
treeef43500ac06c05b1d8417e30cc125cb3e3aeeafa
parent0284027ea11f2fa480ade46bf23d4769748f91f3
tcp_input()'s DELAY_ACK() code checks to see if the delayed ack timer is
running and if it is not it starts it and returns rather then issue an
ack.  If the timer is already running tcp_input() will generate an immediate
ack, resulting in one ack every other packet.  This every-other-packet ack
is usually required to ensure that the window does not close too much and
stall the sender, but it really only exists because the tcp stack does not
look ahead to see if there are other incoming packets that need to be
processed that might themselves require additional acks.  For optimal
operation we really want to process all the pending TCP packets for
the connection before sending any 'normal' acks.

Many ethernet interfaces, including and most especially GigE interfaces,
rate-limit their interrupts.  This results in several packets being moved
from the RX ring to the TCP/IP stack all at once, in a batch.

GIVE THE TCP stack its own netisr dispatcher loop rather then using the
generic netisr dispatcher loop.  The TCP dispatcher loop will call an
additional routine, tcp_willblock(), after all messages queued to the TCP
protocol stack have been exhausted.

When tcp_input() needs to send an ack in the normal header-prediction case
it now places the TCPCB on a queue rather then send an immediate ack.
tcp_willblock() processes this queue and calls tcp_output() to send the
actual ack.

The result is that on a GigE interface which typically queues 8+ packets
per interrupt, a TCP stream will only be acked once per ~8 packets rather
then 4 times (every other packet) per ~8 packets.  This *GREATLY* reduces TCP
protocol overhead and network ack traffic on both ends of the connection.

NOTE: a later commit will deal with pure window space updates which generate
an additional ACK per ~8 packets when the user program drains the buffer.

Reviewed-by: Jeffrey Hsu <hsu@crater.dragonflybsd.org>
sys/netinet/ip_demux.c
sys/netinet/tcp_input.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_var.h