From patchwork Fri Sep 23 06:02:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 116025 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 26545B6F6F for ; Fri, 23 Sep 2011 16:02:38 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751911Ab1IWGCc (ORCPT ); Fri, 23 Sep 2011 02:02:32 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:33233 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751959Ab1IWGCb (ORCPT ); Fri, 23 Sep 2011 02:02:31 -0400 Received: by wyg34 with SMTP id 34so3635036wyg.19 for ; Thu, 22 Sep 2011 23:02:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=subject:from:to:cc:content-type:date:message-id:mime-version :x-mailer:content-transfer-encoding; bh=RSIDihBnstWbm5VYWtXSzkNrsAP5y7+PJ2DxCo00vao=; b=fBI+VdZX1A7ZNuyaMHMfl4takgiv0OuNa21hjZbf8ZHjdUiv8Fo6Cs4kpaUh1Obqtc A7hnxJJ08kwCbOC6YmJ1t9noJWQULyIXSC+VK6lZXhkK+iDLTyEr4jHKM6QhfKjI+dBX VzuizzbSgmb6h5U/YSW41kccr3sRPyfjR+Cpg= Received: by 10.227.60.140 with SMTP id p12mr3293944wbh.30.1316757750117; Thu, 22 Sep 2011 23:02:30 -0700 (PDT) Received: from [192.168.1.21] (184.144.72.86.rev.sfr.net. [86.72.144.184]) by mx.google.com with ESMTPS id u16sm12763794wbm.5.2011.09.22.23.02.26 (version=SSLv3 cipher=OTHER); Thu, 22 Sep 2011 23:02:27 -0700 (PDT) Subject: [PATCH] tcp: ECN blackhole should not force quickack mode From: Eric Dumazet To: David Miller Cc: netdev , Jerry Chu , Ilpo =?ISO-8859-1?Q?J=E4rvinen?= , Jamal Hadi Salim , Jim Gettys , Dave Taht Date: Fri, 23 Sep 2011 08:02:19 +0200 Message-ID: <1316757739.2560.12.camel@edumazet-laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.32.2 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org While playing with a new ADSL box at home, I discovered that ECN blackhole can trigger suboptimal quickack mode on linux : We send one ACK for each incoming data frame, without any delay and eventual piggyback. This is because TCP_ECN_check_ce() considers that if no ECT is seen on a segment, this is because this segment was a retransmit. Refine this heuristic and apply it only if we seen ECT in a previous segment, to detect ECN blackhole at IP level. Signed-off-by: Eric Dumazet CC: Jamal Hadi Salim CC: Jerry Chu CC: Ilpo Järvinen CC: Jim Gettys CC: Dave Taht Acked-by: Ilpo Järvinen --- Another possibility is to remove this (not in RFC 3168) heuristic, what do you think ? include/net/tcp.h | 1 + net/ipv4/tcp_input.c | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/net/tcp.h b/include/net/tcp.h index f357bef..702aefc 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -356,6 +356,7 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, #define TCP_ECN_OK 1 #define TCP_ECN_QUEUE_CWR 2 #define TCP_ECN_DEMAND_CWR 4 +#define TCP_ECN_SEEN 8 static __inline__ void TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a5d01b1..5a4408c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -217,16 +217,25 @@ static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp) tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; } -static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb) +static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *skb) { - if (tp->ecn_flags & TCP_ECN_OK) { - if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags)) - tp->ecn_flags |= TCP_ECN_DEMAND_CWR; + if (!(tp->ecn_flags & TCP_ECN_OK)) + return; + + switch (TCP_SKB_CB(skb)->flags & INET_ECN_MASK) { + case INET_ECN_NOT_ECT: /* Funny extension: if ECT is not set on a segment, - * it is surely retransmit. It is not in ECN RFC, - * but Linux follows this rule. */ - else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags))) + * and we already seen ECT on a previous segment, + * it is probably a retransmit. + */ + if (tp->ecn_flags & TCP_ECN_SEEN) tcp_enter_quickack_mode((struct sock *)tp); + break; + case INET_ECN_CE: + tp->ecn_flags |= TCP_ECN_DEMAND_CWR; + /* fallinto */ + default: + tp->ecn_flags |= TCP_ECN_SEEN; } }