diff options
author | Eric Dumazet <edumazet@google.com> | 2016-05-03 19:56:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-04 16:55:11 -0400 |
commit | 46cc6e4976e3d9058490f20d93bc7805f7f2d81e (patch) | |
tree | 5856b8bab06927f7fc934b7f07a272f5ae680d9c /net/ipv4/tcp_input.c | |
parent | 5332174a83720921a5ef6db8080a8691f7ccbc27 (diff) |
tcp: fix lockdep splat in tcp_snd_una_update()
tcp_snd_una_update() and tcp_rcv_nxt_update() call
u64_stats_update_begin() either from process context or BH handler.
This triggers a lockdep splat on 32bit & SMP builds.
We could add u64_stats_update_begin_bh() variant but this would
slow down 32bit builds with useless local_disable_bh() and
local_enable_bh() pairs, since we own the socket lock at this point.
I add sock_owned_by_me() helper to have proper lockdep support
even on 64bit builds, and new u64_stats_update_begin_raw()
and u64_stats_update_end_raw methods.
Fixes: c10d9310edf5 ("tcp: do not assume TCP code is non preemptible")
Reported-by: Fabio Estevam <festevam@gmail.com>
Diagnosed-by: Francois Romieu <romieu@fr.zoreil.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6171f92be090..a914e0607895 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3355,9 +3355,10 @@ static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack) | |||
3355 | { | 3355 | { |
3356 | u32 delta = ack - tp->snd_una; | 3356 | u32 delta = ack - tp->snd_una; |
3357 | 3357 | ||
3358 | u64_stats_update_begin(&tp->syncp); | 3358 | sock_owned_by_me((struct sock *)tp); |
3359 | u64_stats_update_begin_raw(&tp->syncp); | ||
3359 | tp->bytes_acked += delta; | 3360 | tp->bytes_acked += delta; |
3360 | u64_stats_update_end(&tp->syncp); | 3361 | u64_stats_update_end_raw(&tp->syncp); |
3361 | tp->snd_una = ack; | 3362 | tp->snd_una = ack; |
3362 | } | 3363 | } |
3363 | 3364 | ||
@@ -3366,9 +3367,10 @@ static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq) | |||
3366 | { | 3367 | { |
3367 | u32 delta = seq - tp->rcv_nxt; | 3368 | u32 delta = seq - tp->rcv_nxt; |
3368 | 3369 | ||
3369 | u64_stats_update_begin(&tp->syncp); | 3370 | sock_owned_by_me((struct sock *)tp); |
3371 | u64_stats_update_begin_raw(&tp->syncp); | ||
3370 | tp->bytes_received += delta; | 3372 | tp->bytes_received += delta; |
3371 | u64_stats_update_end(&tp->syncp); | 3373 | u64_stats_update_end_raw(&tp->syncp); |
3372 | tp->rcv_nxt = seq; | 3374 | tp->rcv_nxt = seq; |
3373 | } | 3375 | } |
3374 | 3376 | ||