diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 19 | 
1 files changed, 15 insertions, 4 deletions
| diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index bb3576ac0ad7..b94efb3050d2 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2369,7 +2369,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,  				 u32 max_segs)  {  	const struct inet_connection_sock *icsk = inet_csk(sk); -	u32 send_win, cong_win, limit, in_flight; +	u32 send_win, cong_win, limit, in_flight, threshold; +	u64 srtt_in_ns, expected_ack, how_far_is_the_ack;  	struct tcp_sock *tp = tcp_sk(sk);  	struct sk_buff *head;  	int win_divisor; @@ -2431,9 +2432,19 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,  	head = tcp_rtx_queue_head(sk);  	if (!head)  		goto send_now; -	delta = tp->tcp_clock_cache - head->tstamp; -	/* If next ACK is likely to come too late (half srtt), do not defer */ -	if ((s64)(delta - (u64)NSEC_PER_USEC * (tp->srtt_us >> 4)) < 0) + +	srtt_in_ns = (u64)(NSEC_PER_USEC >> 3) * tp->srtt_us; +	/* When is the ACK expected ? */ +	expected_ack = head->tstamp + srtt_in_ns; +	/* How far from now is the ACK expected ? */ +	how_far_is_the_ack = expected_ack - tp->tcp_clock_cache; + +	/* If next ACK is likely to come too late, +	 * ie in more than min(1ms, half srtt), do not defer. +	 */ +	threshold = min(srtt_in_ns >> 1, NSEC_PER_MSEC); + +	if ((s64)(how_far_is_the_ack - threshold) > 0)  		goto send_now;  	/* Ok, it looks like it is advisable to defer. | 
