diff options
Diffstat (limited to 'net/core/sock.c')
| -rw-r--r-- | net/core/sock.c | 23 | 
1 files changed, 8 insertions, 15 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 79c6aee6af9b..727f924b7f91 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -139,10 +139,7 @@  #include <trace/events/sock.h> -#ifdef CONFIG_INET  #include <net/tcp.h> -#endif -  #include <net/busy_poll.h>  static DEFINE_MUTEX(proto_list_mutex); @@ -1803,28 +1800,24 @@ EXPORT_SYMBOL(skb_set_owner_w);   * delay queue. We want to allow the owner socket to send more   * packets, as if they were already TX completed by a typical driver.   * But we also want to keep skb->sk set because some packet schedulers - * rely on it (sch_fq for example). So we set skb->truesize to a small - * amount (1) and decrease sk_wmem_alloc accordingly. + * rely on it (sch_fq for example).   */  void skb_orphan_partial(struct sk_buff *skb)  { -	/* If this skb is a TCP pure ACK or already went here, -	 * we have nothing to do. 2 is already a very small truesize. -	 */ -	if (skb->truesize <= 2) +	if (skb_is_tcp_pure_ack(skb))  		return; -	/* TCP stack sets skb->ooo_okay based on sk_wmem_alloc, -	 * so we do not completely orphan skb, but transfert all -	 * accounted bytes but one, to avoid unexpected reorders. -	 */  	if (skb->destructor == sock_wfree  #ifdef CONFIG_INET  	    || skb->destructor == tcp_wfree  #endif  		) { -		atomic_sub(skb->truesize - 1, &skb->sk->sk_wmem_alloc); -		skb->truesize = 1; +		struct sock *sk = skb->sk; + +		if (atomic_inc_not_zero(&sk->sk_refcnt)) { +			atomic_sub(skb->truesize, &sk->sk_wmem_alloc); +			skb->destructor = sock_efree; +		}  	} else {  		skb_orphan(skb);  	}  | 
