diff options
Diffstat (limited to 'net/core/sock.c')
| -rw-r--r-- | net/core/sock.c | 27 | 
1 files changed, 21 insertions, 6 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index b0ba569bc97..ba5d2116aea 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -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);  | 
