From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ey0-f171.google.com (mail-ey0-f171.google.com [209.85.215.171]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (verified OK)) by huchra.bufferbloat.net (Postfix) with ESMTPS id ACC0C2005CC for ; Thu, 28 Jun 2012 10:07:23 -0700 (PDT) Received: by eaaa12 with SMTP id a12so1601971eaa.16 for ; Thu, 28 Jun 2012 10:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:from:to:cc:content-type:date:message-id:mime-version :x-mailer:content-transfer-encoding; bh=KmluIyN9zsQrqEw6gTBr3d0WDUsdfWfVDi3WKfdVVBs=; b=eCqSWSOLP/fkqL9rR/lwGhb80mjmAYCSXooy3F7H/beTprAwqnYppsZZzFzwOBw4ph JBmJbTh3VE91Wm4X4DrUL8ytU++l1ZiB+tq9Dhf/ZfgSf/Zu0VJfn5pZOrraFzF5PJPa H/rkb+6I+dpmpUfzLkDJ/wF2xVUmGuDTookypeUE2tHNUsvV822P9+2QVWyqMR6PprUM H5QGL25pOpqRTecnXzPNKWtijcNnNl4UuVFVfP5jMbBB/X8npURDp8JZbvSrMo++1swF ndZwAO4nnBJaDI8vGzJRlsChBrHkpGT8XbTZM6CCn3YKAc6T4lTSoqsvAFyvVKvp8ocW 9cTQ== Received: by 10.14.100.71 with SMTP id y47mr659375eef.190.1340903241114; Thu, 28 Jun 2012 10:07:21 -0700 (PDT) Received: from [172.28.89.75] ([74.125.122.49]) by mx.google.com with ESMTPS id t3sm171079757eeb.15.2012.06.28.10.07.18 (version=SSLv3 cipher=OTHER); Thu, 28 Jun 2012 10:07:20 -0700 (PDT) From: Eric Dumazet To: David Miller Content-Type: text/plain; charset="UTF-8" Date: Thu, 28 Jun 2012 19:07:17 +0200 Message-ID: <1340903237.13187.151.camel@edumazet-glaptop> Mime-Version: 1.0 X-Mailer: Evolution 2.28.3 Content-Transfer-Encoding: 7bit Cc: Nandita Dukkipati , netdev , codel@lists.bufferbloat.net, Yuchung Cheng , Neal Cardwell , Matt Mathis Subject: [Codel] [PATCH net-next] fq_codel: report congestion notification at enqueue time X-BeenThere: codel@lists.bufferbloat.net X-Mailman-Version: 2.1.13 Precedence: list List-Id: CoDel AQM discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Jun 2012 17:07:24 -0000 From: Eric Dumazet At enqueue time, check sojourn time of packet at head of the queue, and return NET_XMIT_CN instead of NET_XMIT_SUCCESS if this sejourn time is above codel @target. This permits local TCP stack to call tcp_enter_cwr() and reduce its cwnd without drops (for example if ECN is not enabled for the flow) Signed-off-by: Eric Dumazet Cc: Dave Taht Cc: Tom Herbert Cc: Matt Mathis Cc: Yuchung Cheng Cc: Nandita Dukkipati Cc: Neal Cardwell --- include/linux/pkt_sched.h | 1 + include/net/codel.h | 2 +- net/sched/sch_fq_codel.c | 19 +++++++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 32aef0a..4d409a5 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -714,6 +714,7 @@ struct tc_fq_codel_qd_stats { */ __u32 new_flows_len; /* count of flows in new list */ __u32 old_flows_len; /* count of flows in old list */ + __u32 congestion_count; }; struct tc_fq_codel_cl_stats { diff --git a/include/net/codel.h b/include/net/codel.h index 550debf..8c7d6a7 100644 --- a/include/net/codel.h +++ b/include/net/codel.h @@ -148,7 +148,7 @@ struct codel_vars { * struct codel_stats - contains codel shared variables and stats * @maxpacket: largest packet we've seen so far * @drop_count: temp count of dropped packets in dequeue() - * ecn_mark: number of packets we ECN marked instead of dropping + * @ecn_mark: number of packets we ECN marked instead of dropping */ struct codel_stats { u32 maxpacket; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 9fc1c62..c0485a0 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -62,6 +62,7 @@ struct fq_codel_sched_data { struct codel_stats cstats; u32 drop_overlimit; u32 new_flow_count; + u32 congestion_count; struct list_head new_flows; /* list of new flows */ struct list_head old_flows; /* list of old flows */ @@ -196,16 +197,25 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) flow->deficit = q->quantum; flow->dropped = 0; } - if (++sch->q.qlen < sch->limit) + if (++sch->q.qlen < sch->limit) { + codel_time_t hdelay = codel_get_enqueue_time(skb) - + codel_get_enqueue_time(flow->head); + + /* If this flow is congested, tell the caller ! */ + if (codel_time_after(hdelay, q->cparams.target)) { + q->congestion_count++; + return NET_XMIT_CN; + } return NET_XMIT_SUCCESS; - + } q->drop_overlimit++; /* Return Congestion Notification only if we dropped a packet * from this flow. */ - if (fq_codel_drop(sch) == idx) + if (fq_codel_drop(sch) == idx) { + q->congestion_count++; return NET_XMIT_CN; - + } /* As we dropped a packet, better let upper stack know this */ qdisc_tree_decrease_qlen(sch, 1); return NET_XMIT_SUCCESS; @@ -467,6 +477,7 @@ static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) st.qdisc_stats.maxpacket = q->cstats.maxpacket; st.qdisc_stats.drop_overlimit = q->drop_overlimit; + st.qdisc_stats.congestion_count = q->congestion_count; st.qdisc_stats.ecn_mark = q->cstats.ecn_mark; st.qdisc_stats.new_flow_count = q->new_flow_count;