forked from mirrors/linux
		
	[TCP]: Fix quick-ack decrementing with TSO.
On each packet output, we call tcp_dec_quickack_mode() if the ACK flag is set. It drops tp->ack.quick until it hits zero, at which time we deflate the ATO value. When doing TSO, we are emitting multiple packets with ACK set, so we should decrement tp->ack.quick that many segments. Note that, unlike this case, tcp_enter_cwr() should not take the tcp_skb_pcount(skb) into consideration. That function, one time, readjusts tp->snd_cwnd and moves into TCP_CA_CWR state. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									c65f7f00c5
								
							
						
					
					
						commit
						fc6415bcb0
					
				
					 2 changed files with 12 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -721,11 +721,16 @@ static inline int tcp_ack_scheduled(struct tcp_sock *tp)
 | 
			
		|||
	return tp->ack.pending&TCP_ACK_SCHED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
 | 
			
		||||
static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts)
 | 
			
		||||
{
 | 
			
		||||
	if (tp->ack.quick && --tp->ack.quick == 0) {
 | 
			
		||||
	if (tp->ack.quick) {
 | 
			
		||||
		if (pkts >= tp->ack.quick) {
 | 
			
		||||
			tp->ack.quick = 0;
 | 
			
		||||
 | 
			
		||||
			/* Leaving quickack mode we deflate ATO. */
 | 
			
		||||
			tp->ack.ato = TCP_ATO_MIN;
 | 
			
		||||
		} else
 | 
			
		||||
			tp->ack.quick -= pkts;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -140,11 +140,11 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp,
 | 
			
		|||
		tp->ack.pingpong = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline__ void tcp_event_ack_sent(struct sock *sk)
 | 
			
		||||
static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 | 
			
		||||
{
 | 
			
		||||
	struct tcp_sock *tp = tcp_sk(sk);
 | 
			
		||||
 | 
			
		||||
	tcp_dec_quickack_mode(tp);
 | 
			
		||||
	tcp_dec_quickack_mode(tp, pkts);
 | 
			
		||||
	tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +355,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 | 
			
		|||
		tp->af_specific->send_check(sk, th, skb->len, skb);
 | 
			
		||||
 | 
			
		||||
		if (tcb->flags & TCPCB_FLAG_ACK)
 | 
			
		||||
			tcp_event_ack_sent(sk);
 | 
			
		||||
			tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
 | 
			
		||||
 | 
			
		||||
		if (skb->len != tcp_header_size)
 | 
			
		||||
			tcp_event_data_sent(tp, skb, sk);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue