diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 27 | 
1 files changed, 19 insertions, 8 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 63170e297540..8c8de2780c7a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1093,6 +1093,13 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)  {  	int i, k, eat; +	eat = min_t(int, len, skb_headlen(skb)); +	if (eat) { +		__skb_pull(skb, eat); +		len -= eat; +		if (!len) +			return; +	}  	eat = len;  	k = 0;  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { @@ -1124,11 +1131,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)  	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))  		return -ENOMEM; -	/* If len == headlen, we avoid __skb_pull to preserve alignment. */ -	if (unlikely(len < skb_headlen(skb))) -		__skb_pull(skb, len); -	else -		__pskb_trim_head(skb, len - skb_headlen(skb)); +	__pskb_trim_head(skb, len);  	TCP_SKB_CB(skb)->seq += len;  	skb->ip_summed = CHECKSUM_PARTIAL; @@ -1581,7 +1584,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)  		 * frame, so if we have space for more than 3 frames  		 * then send now.  		 */ -		if (limit > tcp_max_burst(tp) * tp->mss_cache) +		if (limit > tcp_max_tso_deferred_mss(tp) * tp->mss_cache)  			goto send_now;  	} @@ -1919,7 +1922,7 @@ u32 __tcp_select_window(struct sock *sk)  	if (free_space < (full_space >> 1)) {  		icsk->icsk_ack.quick = 0; -		if (tcp_memory_pressure) +		if (sk_under_memory_pressure(sk))  			tp->rcv_ssthresh = min(tp->rcv_ssthresh,  					       4U * tp->advmss); @@ -2147,7 +2150,15 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)  	 */  	TCP_SKB_CB(skb)->when = tcp_time_stamp; -	err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); +	/* make sure skb->data is aligned on arches that require it */ +	if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { +		struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, +						   GFP_ATOMIC); +		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : +			     -ENOBUFS; +	} else { +		err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); +	}  	if (err == 0) {  		/* Update global TCP statistics. */  |