From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: [PATCH] sch_red: fix red_calc_qavg_from_idle_time Date: Wed, 30 Nov 2011 22:34:51 +0100 Message-ID: <1322688891.2602.15.camel@edumazet-laptop> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Cc: netdev , Stephen Hemminger , David =?ISO-8859-1?Q?T=E4ht?= To: David Miller Return-path: Received: from mail-ee0-f46.google.com ([74.125.83.46]:40116 "EHLO mail-ee0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751493Ab1K3Ve4 (ORCPT ); Wed, 30 Nov 2011 16:34:56 -0500 Received: by eeuu47 with SMTP id u47so664117eeu.19 for ; Wed, 30 Nov 2011 13:34:54 -0800 (PST) Sender: netdev-owner@vger.kernel.org List-ID: Since commit a4a710c4a7490587 (pkt_sched: Change PSCHED_SHIFT from 10 to 6) it seems [G]RED are broken in red_calc_qavg_from_idle_time() This function computes a delay in us units, but this delay is now 16 times bigger than real delay, so the final qavg result is wrong... Signed-off-by: Eric Dumazet --- Maybe we should use native kernel time services in red ? (ktime_get(), ktime_us_delta()) include/net/pkt_sched.h | 1 + include/net/red.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index fffdc60..c719d9b 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -43,6 +43,7 @@ typedef long psched_tdiff_t; /* Avoid doing 64 bit divide */ #define PSCHED_SHIFT 6 #define PSCHED_TICKS2NS(x) ((s64)(x) << PSCHED_SHIFT) +#define PSCHED_TICKS2US(x) (PSCHED_TICKS2NS(x) >> 10) /* approximate 1000 by 1024 */ #define PSCHED_NS2TICKS(x) ((x) >> PSCHED_SHIFT) #define PSCHED_TICKS_PER_SEC PSCHED_NS2TICKS(NSEC_PER_SEC) diff --git a/include/net/red.h b/include/net/red.h index 3319f16..a413638 100644 --- a/include/net/red.h +++ b/include/net/red.h @@ -175,7 +175,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p) int shift; now = psched_get_time(); - us_idle = psched_tdiff_bounded(now, p->qidlestart, p->Scell_max); + us_idle = PSCHED_TICKS2US(psched_tdiff_bounded(now, p->qidlestart, p->Scell_max)); /* * The problem: ideally, average length queue recalcultion should