[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: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
e523a1550e
commit
58a5a7b955
|
@ -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)
|
||||||
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 @@ out:
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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 @@ got_it:
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue