netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tcp: fix false reordering signal in tcp_shifted_skb
@ 2012-02-26 20:06 Neal Cardwell
  2012-02-28 21:06 ` David Miller
  2012-02-29  2:16 ` Yuchung Cheng
  0 siblings, 2 replies; 3+ messages in thread
From: Neal Cardwell @ 2012-02-26 20:06 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, ilpo.jarvinen, Nandita Dukkipati, Yuchung Cheng,
	Tom Herbert, Vijay Subramanian, Neal Cardwell

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@google.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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] tcp: fix false reordering signal in tcp_shifted_skb
  2012-02-26 20:06 [PATCH] tcp: fix false reordering signal in tcp_shifted_skb Neal Cardwell
@ 2012-02-28 21:06 ` David Miller
  2012-02-29  2:16 ` Yuchung Cheng
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2012-02-28 21:06 UTC (permalink / raw)
  To: ncardwell
  Cc: netdev, ilpo.jarvinen, nanditad, ycheng, therbert,
	subramanian.vijay

From: Neal Cardwell <ncardwell@google.com>
Date: Sun, 26 Feb 2012 15:06:19 -0500

> 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@google.com>

Applied and queued up for -stable, thanks Neal.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] tcp: fix false reordering signal in tcp_shifted_skb
  2012-02-26 20:06 [PATCH] tcp: fix false reordering signal in tcp_shifted_skb Neal Cardwell
  2012-02-28 21:06 ` David Miller
@ 2012-02-29  2:16 ` Yuchung Cheng
  1 sibling, 0 replies; 3+ messages in thread
From: Yuchung Cheng @ 2012-02-29  2:16 UTC (permalink / raw)
  To: Neal Cardwell
  Cc: David Miller, netdev, ilpo.jarvinen, Nandita Dukkipati,
	Tom Herbert, Vijay Subramanian

On Sun, Feb 26, 2012 at 12:06 PM, Neal Cardwell <ncardwell@google.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@google.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@google.com>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-02-29  2:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-26 20:06 [PATCH] tcp: fix false reordering signal in tcp_shifted_skb Neal Cardwell
2012-02-28 21:06 ` David Miller
2012-02-29  2:16 ` Yuchung Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).