Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / net / core / sock.c
index b0ba569..ba5d211 100644 (file)
@@ -939,8 +939,23 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
        struct kmem_cache *slab;
 
        slab = prot->slab;
-       if (slab != NULL)
-               sk = kmem_cache_alloc(slab, priority);
+       if (slab != NULL) {
+               sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
+               if (!sk)
+                       return sk;
+               if (priority & __GFP_ZERO) {
+                       /*
+                        * caches using SLAB_DESTROY_BY_RCU should let
+                        * sk_node.next un-modified. Special care is taken
+                        * when initializing object to zero.
+                        */
+                       if (offsetof(struct sock, sk_node.next) != 0)
+                               memset(sk, 0, offsetof(struct sock, sk_node.next));
+                       memset(&sk->sk_node.pprev, 0,
+                              prot->obj_size - offsetof(struct sock,
+                                                        sk_node.pprev));
+               }
+       }
        else
                sk = kmalloc(prot->obj_size, priority);
 
@@ -1715,7 +1730,7 @@ EXPORT_SYMBOL(sock_no_sendpage);
 static void sock_def_wakeup(struct sock *sk)
 {
        read_lock(&sk->sk_callback_lock);
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+       if (sk_has_sleeper(sk))
                wake_up_interruptible_all(sk->sk_sleep);
        read_unlock(&sk->sk_callback_lock);
 }
@@ -1723,7 +1738,7 @@ static void sock_def_wakeup(struct sock *sk)
 static void sock_def_error_report(struct sock *sk)
 {
        read_lock(&sk->sk_callback_lock);
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+       if (sk_has_sleeper(sk))
                wake_up_interruptible_poll(sk->sk_sleep, POLLERR);
        sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
        read_unlock(&sk->sk_callback_lock);
@@ -1732,7 +1747,7 @@ static void sock_def_error_report(struct sock *sk)
 static void sock_def_readable(struct sock *sk, int len)
 {
        read_lock(&sk->sk_callback_lock);
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+       if (sk_has_sleeper(sk))
                wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
                                                POLLRDNORM | POLLRDBAND);
        sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
@@ -1747,7 +1762,7 @@ static void sock_def_write_space(struct sock *sk)
         * progress.  --DaveM
         */
        if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
-               if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+               if (sk_has_sleeper(sk))
                        wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT |
                                                POLLWRNORM | POLLWRBAND);