Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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:
+2 −1
Original line number Original line Diff line number Diff line
@@ -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.
+5 −2
Original line number Original line Diff line number Diff line
@@ -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)


	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)) {
		/*
		/*
+1 −1
Original line number Original line Diff line number Diff line
@@ -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))
+1 −1
Original line number Original line Diff line number Diff line
@@ -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))
Loading