Commit 0a9648f1 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

tcp: add a missing barrier in tcp_tasklet_func()

Madalin reported crashes happening in tcp_tasklet_func() on powerpc64

Before TSQ_QUEUED bit is cleared, we must ensure the changes done
by list_del(&tp->tsq_node); are committed to memory, otherwise
corruption might happen, as an other cpu could catch TSQ_QUEUED
clearance too soon.

We can notice that old kernels were immune to this bug, because
TSQ_QUEUED was cleared after a bh_lock_sock(sk)/bh_unlock_sock(sk)
section, but they could have missed a kick to write additional bytes,
when NIC interrupts for a given flow are spread to multiple cpus.

Affected TCP flows would need an incoming ACK or RTO timer to add more
packets to the pipe. So overall situation should be better now.

Fixes: b223feb9 ("tcp: tsq: add shortcut in tcp_tasklet_func()")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reported-by: default avatarMadalin Bucur <madalin.bucur@nxp.com>
Tested-by: default avatarMadalin Bucur <madalin.bucur@nxp.com>
Tested-by: default avatarXing Lei <xing.lei@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8354491c
...@@ -769,6 +769,7 @@ static void tcp_tasklet_func(unsigned long data) ...@@ -769,6 +769,7 @@ static void tcp_tasklet_func(unsigned long data)
list_del(&tp->tsq_node); list_del(&tp->tsq_node);
sk = (struct sock *)tp; sk = (struct sock *)tp;
smp_mb__before_atomic();
clear_bit(TSQ_QUEUED, &sk->sk_tsq_flags); clear_bit(TSQ_QUEUED, &sk->sk_tsq_flags);
if (!sk->sk_lock.owned && if (!sk->sk_lock.owned &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment