diff options
author | Eric Dumazet <edumazet@google.com> | 2013-12-15 13:53:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-17 14:50:58 -0500 |
commit | e47eb5dfb296bf217e9ebee7b2f07486670b9c1b (patch) | |
tree | cad273de648996d679f3cbfba678b84ff14f40b7 /net/ipv4/udp.c | |
parent | 50dc875f2e6e2e04aed3b3033eb0ac99192d6d02 (diff) |
udp: ipv4: do not use sk_dst_lock from softirq context
Using sk_dst_lock from softirq context is not supported right now.
Instead of adding BH protection everywhere,
udp_sk_rx_dst_set() can instead use xchg(), as suggested
by David.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: 975022310233 ("udp: ipv4: must add synchronization in udp_sk_rx_dst_set()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 13 |
1 files changed, 4 insertions, 9 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 62c19fdd102d..f140048334ce 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1600,20 +1600,15 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | /* For TCP sockets, sk_rx_dst is protected by socket lock | 1602 | /* For TCP sockets, sk_rx_dst is protected by socket lock |
1603 | * For UDP, we use sk_dst_lock to guard against concurrent changes. | 1603 | * For UDP, we use xchg() to guard against concurrent changes. |
1604 | */ | 1604 | */ |
1605 | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | 1605 | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) |
1606 | { | 1606 | { |
1607 | struct dst_entry *old; | 1607 | struct dst_entry *old; |
1608 | 1608 | ||
1609 | spin_lock(&sk->sk_dst_lock); | 1609 | dst_hold(dst); |
1610 | old = sk->sk_rx_dst; | 1610 | old = xchg(&sk->sk_rx_dst, dst); |
1611 | if (likely(old != dst)) { | 1611 | dst_release(old); |
1612 | dst_hold(dst); | ||
1613 | sk->sk_rx_dst = dst; | ||
1614 | dst_release(old); | ||
1615 | } | ||
1616 | spin_unlock(&sk->sk_dst_lock); | ||
1617 | } | 1612 | } |
1618 | 1613 | ||
1619 | /* | 1614 | /* |