Skip to contentSkip to conversation

Patch "tcp: remove poll() flakes with FastOpen" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Mar 22, 2018

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

tcp: remove poll() flakes with FastOpen

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
tcp-remove-poll-flakes-with-fastopen.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Thu Mar 22 14:40:23 CET 2018

From: Eric Dumazet <[email protected]>
Date: Tue, 18 Apr 2017 09:45:52 -0700
Subject: tcp: remove poll() flakes with FastOpen

From: Eric Dumazet <[email protected]>

[ Upstream commit 0f9fa831aecfc297b7b45d4f046759bcefcf87f0 ]

When using TCP FastOpen for an active session, we send one wakeup event from tcp_finish_connect(), right before the data eventually contained in the received SYNACK is queued to sk->sk_receive_queue.

This means that depending on machine load or luck, poll() users might receive POLLOUT events instead of POLLIN|POLLOUT

To fix this, we need to move the call to sk->sk_state_change() after the (optional) call to tcp_rcv_fastopen_synack()

---
 net/ipv4/tcp_input.c |   16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
net/ipv4/tcp_input.c +9 -7
@@ -5606,10 +5606,6 @@ void tcp_finish_connect(struct sock *sk,
 	else
 		tp->pred_flags = 0;
 
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		sk->sk_state_change(sk);
-		sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
-	}
 }
 
 static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
@@ -5678,6 +5674,7 @@ static int tcp_rcv_synsent_state_process
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_fastopen_cookie foc = { .len = -1 };
 	int saved_clamp = tp->rx_opt.mss_clamp;
+	bool fastopen_fail;
 
 	tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
 	if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
@@ -5781,10 +5778,15 @@ static int tcp_rcv_synsent_state_process
 
 		tcp_finish_connect(sk, skb);
 
-		if ((tp->syn_fastopen || tp->syn_data) &&
-		    tcp_rcv_fastopen_synack(sk, skb, &foc))
-			return -1;
+		fastopen_fail = (tp->syn_fastopen || tp->syn_data) &&
+				tcp_rcv_fastopen_synack(sk, skb, &foc);
 
+		if (!sock_flag(sk, SOCK_DEAD)) {
+			sk->sk_state_change(sk);
+			sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
+		}
+		if (fastopen_fail)
+			return -1;
 		if (sk->sk_write_pending ||
 		    icsk->icsk_accept_queue.rskq_defer_accept ||
 		    icsk->icsk_ack.pingpong) {

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/tcp-remove-poll-flakes-with-fastopen.patch