d2b8de6a04e6795568ce35673bb657edc09e184f
[openwrt/openwrt.git] / target / linux / generic / backport-4.9 / 024-9-tcp-add-a-missing-barrier-in-tcp_tasklet_func.patch
1 From 0a9648f1293966c838dc570da73c15a76f4c89d6 Mon Sep 17 00:00:00 2001
2 From: Eric Dumazet <edumazet@google.com>
3 Date: Wed, 21 Dec 2016 05:42:43 -0800
4 Subject: [PATCH 09/10] tcp: add a missing barrier in tcp_tasklet_func()
5
6 Madalin reported crashes happening in tcp_tasklet_func() on powerpc64
7
8 Before TSQ_QUEUED bit is cleared, we must ensure the changes done
9 by list_del(&tp->tsq_node); are committed to memory, otherwise
10 corruption might happen, as an other cpu could catch TSQ_QUEUED
11 clearance too soon.
12
13 We can notice that old kernels were immune to this bug, because
14 TSQ_QUEUED was cleared after a bh_lock_sock(sk)/bh_unlock_sock(sk)
15 section, but they could have missed a kick to write additional bytes,
16 when NIC interrupts for a given flow are spread to multiple cpus.
17
18 Affected TCP flows would need an incoming ACK or RTO timer to add more
19 packets to the pipe. So overall situation should be better now.
20
21 Fixes: b223feb9de2a ("tcp: tsq: add shortcut in tcp_tasklet_func()")
22 Signed-off-by: Eric Dumazet <edumazet@google.com>
23 Reported-by: Madalin Bucur <madalin.bucur@nxp.com>
24 Tested-by: Madalin Bucur <madalin.bucur@nxp.com>
25 Tested-by: Xing Lei <xing.lei@nxp.com>
26 Signed-off-by: David S. Miller <davem@davemloft.net>
27 ---
28 net/ipv4/tcp_output.c | 1 +
29 1 file changed, 1 insertion(+)
30
31 --- a/net/ipv4/tcp_output.c
32 +++ b/net/ipv4/tcp_output.c
33 @@ -769,6 +769,7 @@ static void tcp_tasklet_func(unsigned lo
34 list_del(&tp->tsq_node);
35
36 sk = (struct sock *)tp;
37 + smp_mb__before_atomic();
38 clear_bit(TSQ_QUEUED, &sk->sk_tsq_flags);
39
40 if (!sk->sk_lock.owned &&