[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAK6E8=ehLUL8oZVARCGbh9XL7qu_eMC9XxjXApXyDUvoBADLNQ@mail.gmail.com>
Date: Tue, 28 Feb 2012 18:16:32 -0800
From: Yuchung Cheng <ycheng@...gle.com>
To: Neal Cardwell <ncardwell@...gle.com>
Cc: David Miller <davem@...emloft.net>, netdev@...r.kernel.org,
ilpo.jarvinen@...sinki.fi, Nandita Dukkipati <nanditad@...gle.com>,
Tom Herbert <therbert@...gle.com>,
Vijay Subramanian <subramanian.vijay@...il.com>
Subject: Re: [PATCH] tcp: fix false reordering signal in tcp_shifted_skb
On Sun, Feb 26, 2012 at 12:06 PM, Neal Cardwell <ncardwell@...gle.com> wrote:
> When tcp_shifted_skb() shifts bytes from the skb that is currently
> pointed to by 'highest_sack' then the increment of
> TCP_SKB_CB(skb)->seq implicitly advances tcp_highest_sack_seq(). This
> implicit advancement, combined with the recent fix to pass the correct
> SACKed range into tcp_sacktag_one(), caused tcp_sacktag_one() to think
> that the newly SACKed range was before the tcp_highest_sack_seq(),
> leading to a call to tcp_update_reordering() with a degree of
> reordering matching the size of the newly SACKed range (typically just
> 1 packet, which is a NOP, but potentially larger).
>
> This commit fixes this by simply calling tcp_sacktag_one() before the
> TCP_SKB_CB(skb)->seq advancement that can advance our notion of the
> highest SACKed sequence.
>
> Correspondingly, we can simplify the code a little now that
> tcp_shifted_skb() should update the lost_cnt_hint in all cases where
> skb == tp->lost_skb_hint.
>
> Signed-off-by: Neal Cardwell <ncardwell@...gle.com>
> ---
> net/ipv4/tcp_input.c | 18 ++++++++++--------
> 1 files changed, 10 insertions(+), 8 deletions(-)
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 53c8ce4..ee42d42 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -1403,8 +1403,16 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
>
> BUG_ON(!pcount);
>
> - /* Adjust hint for FACK. Non-FACK is handled in tcp_sacktag_one(). */
> - if (tcp_is_fack(tp) && (skb == tp->lost_skb_hint))
> + /* Adjust counters and hints for the newly sacked sequence
> + * range but discard the return value since prev is already
> + * marked. We must tag the range first because the seq
> + * advancement below implicitly advances
> + * tcp_highest_sack_seq() when skb is highest_sack.
> + */
> + tcp_sacktag_one(sk, state, TCP_SKB_CB(skb)->sacked,
> + start_seq, end_seq, dup_sack, pcount);
> +
> + if (skb == tp->lost_skb_hint)
> tp->lost_cnt_hint += pcount;
>
> TCP_SKB_CB(prev)->end_seq += shifted;
> @@ -1430,12 +1438,6 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
> skb_shinfo(skb)->gso_type = 0;
> }
>
> - /* Adjust counters and hints for the newly sacked sequence range but
> - * discard the return value since prev is already marked.
> - */
> - tcp_sacktag_one(sk, state, TCP_SKB_CB(skb)->sacked,
> - start_seq, end_seq, dup_sack, pcount);
> -
> /* Difference in this won't matter, both ACKed by the same cumul. ACK */
> TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
>
> --
> 1.7.7.3
>
Acked-by: Yuchung Cheng <ycheng@...gle.com>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists