aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Kuznetsov <kuznet@ms2.inr.ac.ru>2006-09-19 15:52:50 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:19:05 -0400
commit1ef9696c909060ccdae3ade245ca88692b49285b (patch)
tree3a2df5bbd6b448a4f873125ab5dd7c7a0cc7ae05
parent4eb327b517cf85f6cb7dcd5691e7b748cbe8c343 (diff)
[TCP]: Send ACKs each 2nd received segment.
It does not affect either mss-sized connections (obviously) or connections controlled by Nagle (because there is only one small segment in flight). The idea is to record the fact that a small segment arrives on a connection, where one small segment has already been received and still not-ACKed. In this case ACK is forced after tcp_recvmsg() drains receive buffer. In other words, it is a "soft" each-2nd-segment ACK, which is enough to preserve ACK clock even when ABC is enabled. Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/inet_connection_sock.h3
-rw-r--r--net/ipv4/tcp.c7
-rw-r--r--net/ipv4/tcp_input.c2
3 files changed, 9 insertions, 3 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 9bf73fe50948..de4e83b6da4b 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -147,7 +147,8 @@ extern struct sock *inet_csk_clone(struct sock *sk,
147enum inet_csk_ack_state_t { 147enum inet_csk_ack_state_t {
148 ICSK_ACK_SCHED = 1, 148 ICSK_ACK_SCHED = 1,
149 ICSK_ACK_TIMER = 2, 149 ICSK_ACK_TIMER = 2,
150 ICSK_ACK_PUSHED = 4 150 ICSK_ACK_PUSHED = 4,
151 ICSK_ACK_PUSHED2 = 8
151}; 152};
152 153
153extern void inet_csk_init_xmit_timers(struct sock *sk, 154extern void inet_csk_init_xmit_timers(struct sock *sk,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 29e3d606db78..66e9a729f6df 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -955,8 +955,11 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
955 * receive buffer and there was a small segment 955 * receive buffer and there was a small segment
956 * in queue. 956 * in queue.
957 */ 957 */
958 (copied > 0 && (icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && 958 (copied > 0 &&
959 !icsk->icsk_ack.pingpong && !atomic_read(&sk->sk_rmem_alloc))) 959 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) ||
960 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
961 !icsk->icsk_ack.pingpong)) &&
962 !atomic_read(&sk->sk_rmem_alloc)))
960 time_to_ack = 1; 963 time_to_ack = 1;
961 } 964 }
962 965
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 511b738f118a..b3def0df14fb 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -156,6 +156,8 @@ static void tcp_measure_rcv_mss(struct sock *sk,
156 return; 156 return;
157 } 157 }
158 } 158 }
159 if (icsk->icsk_ack.pending & ICSK_ACK_PUSHED)
160 icsk->icsk_ack.pending |= ICSK_ACK_PUSHED2;
159 icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; 161 icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
160 } 162 }
161} 163}