Commit 58a5a7b9 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[NET]: Conditionally use bh_lock_sock_nested in sk_receive_skb

Spotted by Ian McDonald, tentatively fixed by Gerrit Renker:

http://www.mail-archive.com/dccp%40vger.kernel.org/msg00599.html

Rewritten not to unroll sk_receive_skb, in the common case, i.e. no lock
debugging, its optimized away.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
parent e523a155
...@@ -393,7 +393,7 @@ static int pppoe_rcv(struct sk_buff *skb, ...@@ -393,7 +393,7 @@ static int pppoe_rcv(struct sk_buff *skb,
po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
if (po != NULL) if (po != NULL)
return sk_receive_skb(sk_pppox(po), skb); return sk_receive_skb(sk_pppox(po), skb, 0);
drop: drop:
kfree_skb(skb); kfree_skb(skb);
out: out:
......
...@@ -954,7 +954,8 @@ static inline void sock_put(struct sock *sk) ...@@ -954,7 +954,8 @@ static inline void sock_put(struct sock *sk)
sk_free(sk); sk_free(sk);
} }
extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb); extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
const int nested);
/* Detach socket from process context. /* Detach socket from process context.
* Announce socket dead, detach it from wait queue and inode. * Announce socket dead, detach it from wait queue and inode.
......
...@@ -270,7 +270,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -270,7 +270,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
} }
EXPORT_SYMBOL(sock_queue_rcv_skb); EXPORT_SYMBOL(sock_queue_rcv_skb);
int sk_receive_skb(struct sock *sk, struct sk_buff *skb) int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
{ {
int rc = NET_RX_SUCCESS; int rc = NET_RX_SUCCESS;
...@@ -279,6 +279,9 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb) ...@@ -279,6 +279,9 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
skb->dev = NULL; skb->dev = NULL;
if (nested)
bh_lock_sock_nested(sk);
else
bh_lock_sock(sk); bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) { if (!sock_owned_by_user(sk)) {
/* /*
......
...@@ -899,7 +899,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) ...@@ -899,7 +899,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
goto discard_and_relse; goto discard_and_relse;
nf_reset(skb); nf_reset(skb);
return sk_receive_skb(sk, skb); return sk_receive_skb(sk, skb, 1);
no_dccp_socket: no_dccp_socket:
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
......
...@@ -888,7 +888,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb) ...@@ -888,7 +888,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse; goto discard_and_relse;
return sk_receive_skb(sk, skb) ? -1 : 0; return sk_receive_skb(sk, skb, 1) ? -1 : 0;
no_dccp_socket: no_dccp_socket:
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
......
...@@ -804,7 +804,7 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -804,7 +804,7 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
goto free_out; goto free_out;
} }
return sk_receive_skb(sk, skb); return sk_receive_skb(sk, skb, 0);
} }
return dn_nsp_no_socket(skb, reason); return dn_nsp_no_socket(skb, reason);
......
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