Skip to content

Commit

Permalink
sch_red: fix red_calc_qavg_from_idle_time
Browse files Browse the repository at this point in the history
Since commit a4a710c (pkt_sched: Change PSCHED_SHIFT from 10 to
6) it seems RED/GRED are broken.

red_calc_qavg_from_idle_time() computes a delay in us units, but this
delay is now 16 times bigger than real delay, so the final qavg result
smaller than expected.

Use standard kernel time services since there is no need to obfuscate
them.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Dec 1, 2011
1 parent 917fbdb commit ea6a5d3
Showing 1 changed file with 6 additions and 9 deletions.
15 changes: 6 additions & 9 deletions include/net/red.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ struct red_parms {
u32 qR; /* Cached random number */

unsigned long qavg; /* Average queue length: A scaled */
psched_time_t qidlestart; /* Start of current idle period */
ktime_t qidlestart; /* Start of current idle period */
};

static inline u32 red_rmask(u8 Plog)
Expand Down Expand Up @@ -148,17 +148,17 @@ static inline void red_set_parms(struct red_parms *p,

static inline int red_is_idling(struct red_parms *p)
{
return p->qidlestart != PSCHED_PASTPERFECT;
return p->qidlestart.tv64 != 0;
}

static inline void red_start_of_idle_period(struct red_parms *p)
{
p->qidlestart = psched_get_time();
p->qidlestart = ktime_get();
}

static inline void red_end_of_idle_period(struct red_parms *p)
{
p->qidlestart = PSCHED_PASTPERFECT;
p->qidlestart.tv64 = 0;
}

static inline void red_restart(struct red_parms *p)
Expand All @@ -170,13 +170,10 @@ static inline void red_restart(struct red_parms *p)

static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
{
psched_time_t now;
long us_idle;
s64 delta = ktime_us_delta(ktime_get(), p->qidlestart);
long us_idle = min_t(s64, delta, p->Scell_max);
int shift;

now = psched_get_time();
us_idle = psched_tdiff_bounded(now, p->qidlestart, p->Scell_max);

/*
* The problem: ideally, average length queue recalcultion should
* be done over constant clock intervals. This is too expensive, so
Expand Down

0 comments on commit ea6a5d3

Please sign in to comment.