@@ -58,6 +58,7 @@ struct pie_vars {
u32 avg_dq_rate; /* bytes per pschedtime tick,scaled */
u32 qlen_old; /* in bytes */
bool active; /* inactive/active */
+ u64 accu_prob; /* accumulated drop probability */
};
/* statistics gathering */
@@ -96,6 +97,7 @@ static void pie_vars_init(struct pie_vars *vars)
/* default of 150 ms in pschedtime */
vars->burst_time = PSCHED_NS2TICKS(150 * NSEC_PER_MSEC);
vars->active = true;
+ vars->accu_prob = 0;
}
static bool drop_early(struct Qdisc *sch, u32 packet_size)
@@ -130,9 +132,21 @@ static bool drop_early(struct Qdisc *sch, u32 packet_size)
else
local_prob = q->vars.prob;
+ if (local_prob == 0)
+ q->vars.accu_prob = 0;
+
+ q->vars.accu_prob += local_prob;
+
+ if (q->vars.accu_prob < (MAX_PROB / 100) * 85)
+ return false;
+ if (q->vars.accu_prob >= ((u64)MAX_PROB * 17) / 2)
+ return true;
+
rnd = prandom_u32();
- if (rnd < local_prob)
+ if (rnd < local_prob) {
+ q->vars.accu_prob = 0;
return true;
+ }
return false;
}
@@ -181,6 +195,7 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
out:
q->stats.dropped++;
+ q->vars.accu_prob = 0;
return qdisc_drop(skb, sch, to_free);
}