From patchwork Mon Feb 7 22:57:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yuchung Cheng X-Patchwork-Id: 82219 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0583EB714A for ; Tue, 8 Feb 2011 09:57:44 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755127Ab1BGW5k (ORCPT ); Mon, 7 Feb 2011 17:57:40 -0500 Received: from smtp-out.google.com ([216.239.44.51]:19973 "EHLO smtp-out.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755093Ab1BGW5j (ORCPT ); Mon, 7 Feb 2011 17:57:39 -0500 Received: from wpaz29.hot.corp.google.com (wpaz29.hot.corp.google.com [172.24.198.93]) by smtp-out.google.com with ESMTP id p17MvWLG031619; Mon, 7 Feb 2011 14:57:32 -0800 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1297119452; bh=LJX02E5vzssx05RH9yoycGF4ssA=; h=From:To:Cc:Subject:Date:Message-Id; b=rVl+inJsEZgBZf/lDK8Nj5xEeIVfYTDbFr5rV0+w0ZbeMFQ/ZpvW+axBOcexqxl1Q xs7udFQzTn9C8z7621nIw== DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=from:to:cc:subject:date:message-id:x-mailer; b=Xarn6Mx/rzY/KS5oVlGYr4VijSuMeTwIFZTXcQZypPJ8zmNqahNJ7qd4eg0uLzdbP /KAyAbm68sPiKOMpyn81w== Received: from blast.mtv.corp.google.com (blast.mtv.corp.google.com [172.22.113.115]) by wpaz29.hot.corp.google.com with ESMTP id p17MvUO1000845; Mon, 7 Feb 2011 14:57:30 -0800 Received: by blast.mtv.corp.google.com (Postfix, from userid 5463) id 7D6D41BE195; Mon, 7 Feb 2011 14:57:30 -0800 (PST) From: Yuchung Cheng To: netdev@vger.kernel.org Cc: ilpo.jarvinen@helsinki.fi, Yuchung Cheng Subject: [PATCH] tcp: undo_retrans counter fixes Date: Mon, 7 Feb 2011 14:57:04 -0800 Message-Id: <1297119424-19956-1-git-send-email-ycheng@google.com> X-Mailer: git-send-email 1.7.3.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Fix a bug that undo_retrans is incorrectly decremented when undo_marker is not set or undo_retrans is already 0. This happens when sender receives more DSACK ACKs than packets retransmitted during the current undo phase. This may also happen when sender receives DSACK after the undo operation is completed or cancelled. Fix another bug that undo_retrans is incorrectly incremented when sender retransmits an skb and tcp_skb_pcount(skb) > 1 (TSO). This case is rare but not impossible. Signed-off-by: Yuchung Cheng Acked-by: Ilpo Järvinen --- net/ipv4/tcp_input.c | 5 +++-- net/ipv4/tcp_output.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2f692ce..08ea735 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1222,7 +1222,7 @@ static int tcp_check_dsack(struct sock *sk, struct sk_buff *ack_skb, } /* D-SACK for already forgotten data... Do dumb counting. */ - if (dup_sack && + if (dup_sack && tp->undo_marker && tp->undo_retrans && !after(end_seq_0, prior_snd_una) && after(end_seq_0, tp->undo_marker)) tp->undo_retrans--; @@ -1299,7 +1299,8 @@ static u8 tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, /* Account D-SACK for retransmitted packet. */ if (dup_sack && (sacked & TCPCB_RETRANS)) { - if (after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker)) + if (tp->undo_marker && tp->undo_retrans && + after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker)) tp->undo_retrans--; if (sacked & TCPCB_SACKED_ACKED) state->reord = min(fack_count, state->reord); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 406f320..dfa5beb 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2162,7 +2162,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) if (!tp->retrans_stamp) tp->retrans_stamp = TCP_SKB_CB(skb)->when; - tp->undo_retrans++; + tp->undo_retrans += tcp_skb_pcount(skb); /* snd_nxt is stored to detect loss of retransmitted segment, * see tcp_input.c tcp_sacktag_write_queue().