Commit 1ef9696c authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller
Browse files

[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: default avatarAlexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4eb327b5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -147,7 +147,8 @@ extern struct sock *inet_csk_clone(struct sock *sk,
enum inet_csk_ack_state_t {
	ICSK_ACK_SCHED	= 1,
	ICSK_ACK_TIMER  = 2,
	ICSK_ACK_PUSHED = 4
	ICSK_ACK_PUSHED = 4,
	ICSK_ACK_PUSHED2 = 8
};

extern void inet_csk_init_xmit_timers(struct sock *sk,
+5 −2
Original line number Diff line number Diff line
@@ -955,8 +955,11 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
		     * receive buffer and there was a small segment
		     * in queue.
		     */
		    (copied > 0 && (icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
		     !icsk->icsk_ack.pingpong && !atomic_read(&sk->sk_rmem_alloc)))
		    (copied > 0 &&
		     ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) ||
		      ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
		       !icsk->icsk_ack.pingpong)) &&
		      !atomic_read(&sk->sk_rmem_alloc)))
			time_to_ack = 1;
	}

+2 −0
Original line number Diff line number Diff line
@@ -156,6 +156,8 @@ static void tcp_measure_rcv_mss(struct sock *sk,
				return;
			}
		}
		if (icsk->icsk_ack.pending & ICSK_ACK_PUSHED)
			icsk->icsk_ack.pending |= ICSK_ACK_PUSHED2;
		icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
	}
}