aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2005-07-05 18:17:45 -0400
committerDavid S. Miller <davem@davemloft.net>2005-07-05 18:17:45 -0400
commitfc6415bcb0f58f03adb910e56d7e1df6368794e0 (patch)
tree71c326c1176e87c57c80cb32d9049b813f58bced
parentc65f7f00c587828e3d50737805a78f74804972de (diff)
[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>
-rw-r--r--include/net/tcp.h13
-rw-r--r--net/ipv4/tcp_output.c6
2 files changed, 12 insertions, 7 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ec9e20c27179..afe41c5de2f2 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -721,11 +721,16 @@ static inline int tcp_ack_scheduled(struct tcp_sock *tp)
721 return tp->ack.pending&TCP_ACK_SCHED; 721 return tp->ack.pending&TCP_ACK_SCHED;
722} 722}
723 723
724static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp) 724static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts)
725{ 725{
726 if (tp->ack.quick && --tp->ack.quick == 0) { 726 if (tp->ack.quick) {
727 /* Leaving quickack mode we deflate ATO. */ 727 if (pkts >= tp->ack.quick) {
728 tp->ack.ato = TCP_ATO_MIN; 728 tp->ack.quick = 0;
729
730 /* Leaving quickack mode we deflate ATO. */
731 tp->ack.ato = TCP_ATO_MIN;
732 } else
733 tp->ack.quick -= pkts;
729 } 734 }
730} 735}
731 736
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 0e17c244875c..389deeb2a457 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -140,11 +140,11 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp,
140 tp->ack.pingpong = 1; 140 tp->ack.pingpong = 1;
141} 141}
142 142
143static __inline__ void tcp_event_ack_sent(struct sock *sk) 143static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
144{ 144{
145 struct tcp_sock *tp = tcp_sk(sk); 145 struct tcp_sock *tp = tcp_sk(sk);
146 146
147 tcp_dec_quickack_mode(tp); 147 tcp_dec_quickack_mode(tp, pkts);
148 tcp_clear_xmit_timer(sk, TCP_TIME_DACK); 148 tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
149} 149}
150 150
@@ -355,7 +355,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
355 tp->af_specific->send_check(sk, th, skb->len, skb); 355 tp->af_specific->send_check(sk, th, skb->len, skb);
356 356
357 if (tcb->flags & TCPCB_FLAG_ACK) 357 if (tcb->flags & TCPCB_FLAG_ACK)
358 tcp_event_ack_sent(sk); 358 tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
359 359
360 if (skb->len != tcp_header_size) 360 if (skb->len != tcp_header_size)
361 tcp_event_data_sent(tp, skb, sk); 361 tcp_event_data_sent(tp, skb, sk);