net: Fix percpu counters deadlock
[pandora-kernel.git] / net / ipv6 / tcp_ipv6.c
index a5d750a..e8b8337 100644 (file)
@@ -23,6 +23,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+#include <linux/bottom_half.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -260,7 +261,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
+       err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
+       if (err < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -390,7 +392,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                                goto out;
                        }
 
-                       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+                       if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) {
                                sk->sk_err_soft = -err;
                                goto out;
                        }
@@ -492,7 +494,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
                goto done;
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+       if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
                goto done;
 
        skb = tcp_make_synack(sk, dst, req);
@@ -1018,7 +1020,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
         * namespace
         */
        if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
-               if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
+               if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) {
                        ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
                        TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
                        if (rst)
@@ -1316,7 +1318,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                if (final_p)
                        ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-               if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+               if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
                        goto out;
        }
 
@@ -1829,7 +1831,9 @@ static int tcp_v6_init_sock(struct sock *sk)
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
        sk->sk_rcvbuf = sysctl_tcp_rmem[1];
 
-       atomic_inc(&tcp_sockets_allocated);
+       local_bh_disable();
+       percpu_counter_inc(&tcp_sockets_allocated);
+       local_bh_enable();
 
        return 0;
 }