Commit 3f7ae5f3 authored by Mohit P. Tahiliani's avatar Mohit P. Tahiliani Committed by David S. Miller

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: default avatarMohit P. Tahiliani <tahiliani@nitk.edu.in>
Signed-off-by: default avatarDhaval Khandla <dhavaljkhandla26@gmail.com>
Signed-off-by: default avatarHrishikesh Hiraskar <hrishihiraskar@gmail.com>
Signed-off-by: default avatarManish Kumar B <bmanish15597@gmail.com>
Signed-off-by: default avatarSachin D. Patil <sdp.sachin@gmail.com>
Signed-off-by: default avatarLeslie Monis <lesliemonis@gmail.com>
Acked-by: default avatarDave Taht <dave.taht@gmail.com>
Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 30a92ad7
...@@ -954,7 +954,7 @@ enum { ...@@ -954,7 +954,7 @@ enum {
#define TCA_PIE_MAX (__TCA_PIE_MAX - 1) #define TCA_PIE_MAX (__TCA_PIE_MAX - 1)
struct tc_pie_xstats { struct tc_pie_xstats {
__u32 prob; /* current probability */ __u64 prob; /* current probability */
__u32 delay; /* current delay in ms */ __u32 delay; /* current delay in ms */
__u32 avg_dq_rate; /* current average dq_rate in bits/pie_time */ __u32 avg_dq_rate; /* current average dq_rate in bits/pie_time */
__u32 packets_in; /* total number of packets enqueued */ __u32 packets_in; /* total number of packets enqueued */
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define QUEUE_THRESHOLD 16384 #define QUEUE_THRESHOLD 16384
#define DQCOUNT_INVALID -1 #define DQCOUNT_INVALID -1
#define MAX_PROB 0xffffffff #define MAX_PROB 0xffffffffffffffff
#define PIE_SCALE 8 #define PIE_SCALE 8
/* parameters used */ /* parameters used */
...@@ -49,7 +49,7 @@ struct pie_params { ...@@ -49,7 +49,7 @@ struct pie_params {
/* variables used */ /* variables used */
struct pie_vars { 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 burst_time;
psched_time_t qdelay; psched_time_t qdelay;
psched_time_t qdelay_old; psched_time_t qdelay_old;
...@@ -99,8 +99,8 @@ static void pie_vars_init(struct pie_vars *vars) ...@@ -99,8 +99,8 @@ static void pie_vars_init(struct pie_vars *vars)
static bool drop_early(struct Qdisc *sch, u32 packet_size) static bool drop_early(struct Qdisc *sch, u32 packet_size)
{ {
struct pie_sched_data *q = qdisc_priv(sch); struct pie_sched_data *q = qdisc_priv(sch);
u32 rnd; u64 rnd;
u32 local_prob = q->vars.prob; u64 local_prob = q->vars.prob;
u32 mtu = psched_mtu(qdisc_dev(sch)); u32 mtu = psched_mtu(qdisc_dev(sch));
/* If there is still burst allowance left skip random early drop */ /* 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) ...@@ -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 * probablity. Smaller packets will have lower drop prob in this case
*/ */
if (q->params.bytemode && packet_size <= mtu) 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 else
local_prob = q->vars.prob; local_prob = q->vars.prob;
rnd = prandom_u32(); prandom_bytes(&rnd, 8);
if (rnd < local_prob) if (rnd < local_prob)
return true; return true;
...@@ -317,9 +317,10 @@ static void calculate_probability(struct Qdisc *sch) ...@@ -317,9 +317,10 @@ static void calculate_probability(struct Qdisc *sch)
u32 qlen = sch->qstats.backlog; /* queue size in bytes */ u32 qlen = sch->qstats.backlog; /* queue size in bytes */
psched_time_t qdelay = 0; /* in pschedtime */ psched_time_t qdelay = 0; /* in pschedtime */
psched_time_t qdelay_old = q->vars.qdelay; /* in pschedtime */ psched_time_t qdelay_old = q->vars.qdelay; /* in pschedtime */
s32 delta = 0; /* determines the change in probability */ s64 delta = 0; /* determines the change in probability */
u32 oldprob; u64 oldprob;
u32 alpha, beta; u64 alpha, beta;
u32 power;
bool update_prob = true; bool update_prob = true;
q->vars.qdelay_old = q->vars.qdelay; q->vars.qdelay_old = q->vars.qdelay;
...@@ -339,38 +340,36 @@ static void calculate_probability(struct Qdisc *sch) ...@@ -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 * 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 * 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 * 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 * probability. alpha/beta are updated locally below by scaling down
* appropriately 2) scaling down by 16 to come to 0-2 range. * 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.
*/ */
if (q->vars.prob < MAX_PROB / 100) { alpha = ((u64)q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
alpha = beta = ((u64)q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 7;
beta = /* We scale alpha and beta differently depending on how heavy the
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 7; * congestion is. Please see RFC 8033 for details.
} else if (q->vars.prob < MAX_PROB / 10) { */
alpha = if (q->vars.prob < MAX_PROB / 10) {
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 5; alpha >>= 1;
beta = beta >>= 1;
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 5;
} else { power = 100;
alpha = while (q->vars.prob < div_u64(MAX_PROB, power) &&
(q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4; power <= 1000000) {
beta = alpha >>= 2;
(q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4; beta >>= 2;
power *= 10;
}
} }
/* alpha and beta should be between 0 and 32, in multiples of 1/16 */ /* alpha and beta should be between 0 and 32, in multiples of 1/16 */
delta += alpha * ((qdelay - q->params.target)); delta += alpha * (u64)(qdelay - q->params.target);
delta += beta * ((qdelay - qdelay_old)); delta += beta * (u64)(qdelay - qdelay_old);
oldprob = q->vars.prob; oldprob = q->vars.prob;
/* to ensure we increase probability in steps of no more than 2% */ /* 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) q->vars.prob >= MAX_PROB / 10)
delta = (MAX_PROB / 100) * 2; delta = (MAX_PROB / 100) * 2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment