aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-08-09 00:35:05 -0700
committerDavid S. Miller <davem@davemloft.net>2008-08-09 00:35:05 -0700
commitd97106ea52aa57e63ff40d04479016836bbb5a4e (patch)
tree5969603d7af02a5672f61c84c2017a6e064472f5
parent8123b421e8ed944671d7241323ed3198cccb4041 (diff)
udp: Drop socket lock for encapsulated packets
The socket lock is there to protect the normal UDP receive path. Encapsulation UDP sockets don't need that protection. In fact the locking is deadly for them as they may contain another UDP packet within, possibly with the same addresses. Also the nested bit was copied from TCP. TCP needs it because of accept(2) spawning sockets. This simply doesn't apply to UDP so I've removed it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/udp.c6
-rw-r--r--net/ipv6/udp.c6
2 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 383d17359d0..8e42fbbd576 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -989,7 +989,9 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
up->encap_rcv != NULL) {
int ret;
+ bh_unlock_sock(sk);
ret = (*up->encap_rcv)(sk, skb);
+ bh_lock_sock(sk);
if (ret <= 0) {
UDP_INC_STATS_BH(sock_net(sk),
UDP_MIB_INDATAGRAMS,
@@ -1092,7 +1094,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
if (skb1) {
int ret = 0;
- bh_lock_sock_nested(sk);
+ bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
ret = udp_queue_rcv_skb(sk, skb1);
else
@@ -1194,7 +1196,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (sk != NULL) {
int ret = 0;
- bh_lock_sock_nested(sk);
+ bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
ret = udp_queue_rcv_skb(sk, skb);
else
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d1477b350f7..a6aecf76a71 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -379,7 +379,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
uh->source, saddr, dif))) {
struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
if (buff) {
- bh_lock_sock_nested(sk2);
+ bh_lock_sock(sk2);
if (!sock_owned_by_user(sk2))
udpv6_queue_rcv_skb(sk2, buff);
else
@@ -387,7 +387,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
bh_unlock_sock(sk2);
}
}
- bh_lock_sock_nested(sk);
+ bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb);
else
@@ -508,7 +508,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
/* deliver */
- bh_lock_sock_nested(sk);
+ bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb);
else