[NET]: Conditionally use bh_lock_sock_nested in sk_receive_skb
authorArnaldo Carvalho de Melo <acme@mandriva.com>
Thu, 16 Nov 2006 16:06:06 +0000 (14:06 -0200)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 3 Dec 2006 05:23:51 +0000 (21:23 -0800)
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>
drivers/net/pppoe.c
include/net/sock.h
net/core/sock.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/decnet/dn_nsp_in.c

index 0adee733b76121126c4cbfcf0cbed8f9aadbc087..315d5c3fc66a0d9480bbc871f14b1b442cc78870 100644 (file)
@@ -393,7 +393,7 @@ static int pppoe_rcv(struct sk_buff *skb,
 
        po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
        if (po != NULL)
-               return sk_receive_skb(sk_pppox(po), skb);
+               return sk_receive_skb(sk_pppox(po), skb, 0);
 drop:
        kfree_skb(skb);
 out:
index dc4b92b8abea93068d231562288ab2563236e573..26fc0b16bc0cf5ab394d17ba1bc059407f6150e4 100644 (file)
@@ -954,7 +954,8 @@ static inline void sock_put(struct sock *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.
  * Announce socket dead, detach it from wait queue and inode.
index 32ff1c551d699baff9e875a6b2e7fd16fb9b8c4b..ab8fafadb4ba1f9afe8a1b8a96741e27fc74472c 100644 (file)
@@ -270,7 +270,7 @@ out:
 }
 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;
 
@@ -279,7 +279,10 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
 
        skb->dev = NULL;
 
-       bh_lock_sock(sk);
+       if (nested)
+               bh_lock_sock_nested(sk);
+       else
+               bh_lock_sock(sk);
        if (!sock_owned_by_user(sk)) {
                /*
                 * trylock + unlock semantics:
index a20eb71d45db8cdd66cd7946c9de25150f5cc27f..7114befe7d50467b3b92c45f745048e3646e6a92 100644 (file)
@@ -899,7 +899,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
                goto discard_and_relse;
        nf_reset(skb);
 
-       return sk_receive_skb(sk, skb);
+       return sk_receive_skb(sk, skb, 1);
 
 no_dccp_socket:
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
index 6eda430ae92961c1089cf4095d673f88679da907..03bb8298250a04cbd317e3c5aaa5168a7cfe6232 100644 (file)
@@ -888,7 +888,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_and_relse;
 
-       return sk_receive_skb(sk, skb) ? -1 : 0;
+       return sk_receive_skb(sk, skb, 1) ? -1 : 0;
 
 no_dccp_socket:
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
index 7683d4f754d269dfd642fc92f43cbd1c7bab72dc..39a6cf7fb5660b2cf4187a341e0868450c1de369 100644 (file)
@@ -804,7 +804,7 @@ got_it:
                                goto free_out;
                }
 
-               return sk_receive_skb(sk, skb);
+               return sk_receive_skb(sk, skb, 0);
        }
 
        return dn_nsp_no_socket(skb, reason);