From e47eb5dfb296bf217e9ebee7b2f07486670b9c1b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 15 Dec 2013 10:53:46 -0800 Subject: [PATCH] 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 Fixes: 975022310233 ("udp: ipv4: must add synchronization in udp_sk_rx_dst_set()") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/udp.c | 13 ++++--------- 1 file 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, } /* For TCP sockets, sk_rx_dst is protected by socket lock - * For UDP, we use sk_dst_lock to guard against concurrent changes. + * For UDP, we use xchg() to guard against concurrent changes. */ static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) { struct dst_entry *old; - spin_lock(&sk->sk_dst_lock); - old = sk->sk_rx_dst; - if (likely(old != dst)) { - dst_hold(dst); - sk->sk_rx_dst = dst; - dst_release(old); - } - spin_unlock(&sk->sk_dst_lock); + dst_hold(dst); + old = xchg(&sk->sk_rx_dst, dst); + dst_release(old); } /* -- 2.39.5