net: sk_free() should be allowed right after sk_alloc()
authorJarek Poplawski <jarkao2@gmail.com>
Sun, 30 Aug 2009 23:15:36 +0000 (23:15 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Sep 2009 00:49:00 +0000 (17:49 -0700)
After commit 2b85a34e911bf483c27cfdd124aeb1605145dc80
(net: No more expensive sock_hold()/sock_put() on each tx)
sk_free() frees socks conditionally and depends
on sk_wmem_alloc being set e.g. in sock_init_data(). But in some
cases sk_free() is called earlier, usually after other alloc errors.

Fix is to move sk_wmem_alloc initialization from sock_init_data()
to sk_alloc() itself.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/sock.c

index bbb25be7ddfe614432ca8627ba4cbe791f57d569..76334228ed1c36e93513a3236957476c1e13291e 100644 (file)
@@ -1025,6 +1025,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
                sk->sk_prot = sk->sk_prot_creator = prot;
                sock_lock_init(sk);
                sock_net_set(sk, get_net(net));
+               atomic_set(&sk->sk_wmem_alloc, 1);
        }
 
        return sk;
@@ -1872,7 +1873,6 @@ void sock_init_data(struct socket *sock, struct sock *sk)
         */
        smp_wmb();
        atomic_set(&sk->sk_refcnt, 1);
-       atomic_set(&sk->sk_wmem_alloc, 1);
        atomic_set(&sk->sk_drops, 0);
 }
 EXPORT_SYMBOL(sock_init_data);