]> git.baikalelectronics.ru Git - kernel.git/commit
tcp: try to keep packet if SYN_RCV race is lost
authorEric Dumazet <edumazet@google.com>
Tue, 13 Feb 2018 14:14:12 +0000 (06:14 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Feb 2018 19:21:45 +0000 (14:21 -0500)
commit2b027671dde9cb6409d9d4d4f1c3c5f84a3826a0
tree8f384615d4648a8fc46c70db06dd9021a0a480b4
parent87bdb90bef1cb3d78aa669e3e317102c4a81f0ef
tcp: try to keep packet if SYN_RCV race is lost

배석진 reported that in some situations, packets for a given 5-tuple
end up being processed by different CPUS.

This involves RPS, and fragmentation.

배석진 is seeing packet drops when a SYN_RECV request socket is
moved into ESTABLISH state. Other states are protected by socket lock.

This is caused by a CPU losing the race, and simply not caring enough.

Since this seems to occur frequently, we can do better and perform
a second lookup.

Note that all needed memory barriers are already in the existing code,
thanks to the spin_lock()/spin_unlock() pair in inet_ehash_insert()
and reqsk_put(). The second lookup must find the new socket,
unless it has already been accepted and closed by another cpu.

Note that the fragmentation could be avoided in the first place by
use of a correct TCP MSS option in the SYN{ACK} packet, but this
does not mean we can not be more robust.

Many thanks to 배석진 for a very detailed analysis.

Reported-by: 배석진 <soukjin.bae@samsung.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/tcp_ipv6.c