forked from Minki/linux
net: sched: pie: add more cases to auto-tune alpha and beta
The current implementation scales the local alpha and beta variables in the calculate_probability function by the same amount for all values of drop probability below 1%. RFC 8033 suggests using additional cases for auto-tuning alpha and beta when the drop probability is less than 1%. In order to add more auto-tuning cases, MAX_PROB must be scaled by u64 instead of u32 to prevent underflow when scaling the local alpha and beta variables in the calculate_probability function. Signed-off-by: Mohit P. Tahiliani <tahiliani@nitk.edu.in> Signed-off-by: Dhaval Khandla <dhavaljkhandla26@gmail.com> Signed-off-by: Hrishikesh Hiraskar <hrishihiraskar@gmail.com> Signed-off-by: Manish Kumar B <bmanish15597@gmail.com> Signed-off-by: Sachin D. Patil <sdp.sachin@gmail.com> Signed-off-by: Leslie Monis <lesliemonis@gmail.com> Acked-by: Dave Taht <dave.taht@gmail.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
30a92ad703
commit
3f7ae5f3dc
@ -954,7 +954,7 @@ enum {
|
||||
#define TCA_PIE_MAX (__TCA_PIE_MAX - 1)
|
||||
|
||||
struct tc_pie_xstats {
|
||||
__u32 prob; /* current probability */
|
||||
__u64 prob; /* current probability */
|
||||
__u32 delay; /* current delay in ms */
|
||||
__u32 avg_dq_rate; /* current average dq_rate in bits/pie_time */
|
||||
__u32 packets_in; /* total number of packets enqueued */
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#define QUEUE_THRESHOLD 16384
|
||||
#define DQCOUNT_INVALID -1
|
||||
#define MAX_PROB 0xffffffff
|
||||
#define MAX_PROB 0xffffffffffffffff
|
||||
#define PIE_SCALE 8
|
||||
|
||||
/* parameters used */
|
||||
@ -49,7 +49,7 @@ struct pie_params {
|
||||
|
||||
/* variables used */
|
||||
struct pie_vars {
|
||||
u32 prob; /* probability but scaled by u32 limit. */
|
||||
u64 prob; /* probability but scaled by u64 limit. */
|
||||
psched_time_t burst_time;
|
||||
psched_time_t qdelay;
|
||||
psched_time_t qdelay_old;
|
||||
@ -99,8 +99,8 @@ static void pie_vars_init(struct pie_vars *vars)
|
||||
static bool drop_early(struct Qdisc *sch, u32 packet_size)
|
||||
{
|
||||
struct pie_sched_data *q = qdisc_priv(sch);
|
||||
u32 rnd;
|
||||
u32 local_prob = q->vars.prob;
|
||||
u64 rnd;
|
||||
u64 local_prob = q->vars.prob;
|
||||
u32 mtu = psched_mtu(qdisc_dev(sch));
|
||||
|
||||
/* If there is still burst allowance left skip random early drop */
|
||||
@ -124,11 +124,11 @@ static bool drop_early(struct Qdisc *sch, u32 packet_size)
|
||||
* probablity. Smaller packets will have lower drop prob in this case
|
||||
*/
|
||||
if (q->params.bytemode && packet_size <= mtu)
|
||||
local_prob = (local_prob / mtu) * packet_size;
|
||||
local_prob = (u64)packet_size * div_u64(local_prob, mtu);
|
||||
else
|
||||
local_prob = q->vars.prob;
|
||||
|
||||
rnd = prandom_u32();
|
||||
prandom_bytes(&rnd, 8);
|
||||
if (rnd < local_prob)
|
||||
return true;
|
||||
|
||||
@ -317,9 +317,10 @@ static void calculate_probability(struct Qdisc *sch)
|
||||
u32 qlen = sch->qstats.backlog; /* queue size in bytes */
|
||||
psched_time_t qdelay = 0; /* in pschedtime */
|
||||
psched_time_t qdelay_old = q->vars.qdelay; /* in pschedtime */
|
||||
s32 delta = 0; /* determines the change in probability */
|
||||
u32 oldprob;
|
||||
u32 alpha, beta;
|
||||
s64 delta = 0; /* determines the change in probability */
|
||||
u64 oldprob;
|
||||
u64 alpha, beta;
|
||||
u32 power;
|
||||
bool update_prob = true;
|
||||
|
||||
q->vars.qdelay_old = q->vars.qdelay;
|
||||
@ -339,38 +340,36 @@ static void calculate_probability(struct Qdisc *sch)
|
||||
* value for alpha as 0.125. In this implementation, we use values 0-32
|
||||
* passed from user space to represent this. Also, alpha and beta have
|
||||
* unit of HZ and need to be scaled before they can used to update
|
||||
* probability. alpha/beta are updated locally below by 1) scaling them
|
||||
* appropriately 2) scaling down by 16 to come to 0-2 range.
|
||||
* Please see paper for details.
|
||||
*
|
||||
* We scale alpha and beta differently depending on whether we are in
|
||||
* light, medium or high dropping mode.
|
||||
* probability. alpha/beta are updated locally below by scaling down
|
||||
* by 16 to come to 0-2 range.
|
||||
*/
|
||||
if (q->vars.prob < MAX_PROB / 100) {
|
||||
alpha =
|
||||
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 7;
|
||||
beta =
|
||||
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 7;
|
||||
} else if (q->vars.prob < MAX_PROB / 10) {
|
||||
alpha =
|
||||
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 5;
|
||||
beta =
|
||||
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 5;
|
||||
} else {
|
||||
alpha =
|
||||
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
|
||||
beta =
|
||||
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
|
||||
alpha = ((u64)q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
|
||||
beta = ((u64)q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
|
||||
|
||||
/* We scale alpha and beta differently depending on how heavy the
|
||||
* congestion is. Please see RFC 8033 for details.
|
||||
*/
|
||||
if (q->vars.prob < MAX_PROB / 10) {
|
||||
alpha >>= 1;
|
||||
beta >>= 1;
|
||||
|
||||
power = 100;
|
||||
while (q->vars.prob < div_u64(MAX_PROB, power) &&
|
||||
power <= 1000000) {
|
||||
alpha >>= 2;
|
||||
beta >>= 2;
|
||||
power *= 10;
|
||||
}
|
||||
}
|
||||
|
||||
/* alpha and beta should be between 0 and 32, in multiples of 1/16 */
|
||||
delta += alpha * ((qdelay - q->params.target));
|
||||
delta += beta * ((qdelay - qdelay_old));
|
||||
delta += alpha * (u64)(qdelay - q->params.target);
|
||||
delta += beta * (u64)(qdelay - qdelay_old);
|
||||
|
||||
oldprob = q->vars.prob;
|
||||
|
||||
/* to ensure we increase probability in steps of no more than 2% */
|
||||
if (delta > (s32)(MAX_PROB / (100 / 2)) &&
|
||||
if (delta > (s64)(MAX_PROB / (100 / 2)) &&
|
||||
q->vars.prob >= MAX_PROB / 10)
|
||||
delta = (MAX_PROB / 100) * 2;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user