diff options
-rw-r--r-- | include/linux/pkt_sched.h | 2 | ||||
-rw-r--r-- | include/net/red.h | 16 | ||||
-rw-r--r-- | net/sched/sch_choke.c | 8 | ||||
-rw-r--r-- | net/sched/sch_gred.c | 22 | ||||
-rw-r--r-- | net/sched/sch_red.c | 9 |
5 files changed, 45 insertions, 12 deletions
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index e41e0d4de24b..8786ea741f52 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h | |||
@@ -216,6 +216,7 @@ enum { | |||
216 | TCA_GRED_PARMS, | 216 | TCA_GRED_PARMS, |
217 | TCA_GRED_STAB, | 217 | TCA_GRED_STAB, |
218 | TCA_GRED_DPS, | 218 | TCA_GRED_DPS, |
219 | TCA_GRED_MAX_P, | ||
219 | __TCA_GRED_MAX, | 220 | __TCA_GRED_MAX, |
220 | }; | 221 | }; |
221 | 222 | ||
@@ -255,6 +256,7 @@ enum { | |||
255 | TCA_CHOKE_UNSPEC, | 256 | TCA_CHOKE_UNSPEC, |
256 | TCA_CHOKE_PARMS, | 257 | TCA_CHOKE_PARMS, |
257 | TCA_CHOKE_STAB, | 258 | TCA_CHOKE_STAB, |
259 | TCA_CHOKE_MAX_P, | ||
258 | __TCA_CHOKE_MAX, | 260 | __TCA_CHOKE_MAX, |
259 | }; | 261 | }; |
260 | 262 | ||
diff --git a/include/net/red.h b/include/net/red.h index 24606b22d01e..ef715a16cce4 100644 --- a/include/net/red.h +++ b/include/net/red.h | |||
@@ -155,9 +155,10 @@ static inline u32 red_maxp(u8 Plog) | |||
155 | 155 | ||
156 | static inline void red_set_parms(struct red_parms *p, | 156 | static inline void red_set_parms(struct red_parms *p, |
157 | u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, | 157 | u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, |
158 | u8 Scell_log, u8 *stab) | 158 | u8 Scell_log, u8 *stab, u32 max_P) |
159 | { | 159 | { |
160 | int delta = qth_max - qth_min; | 160 | int delta = qth_max - qth_min; |
161 | u32 max_p_delta; | ||
161 | 162 | ||
162 | /* Reset average queue length, the value is strictly bound | 163 | /* Reset average queue length, the value is strictly bound |
163 | * to the parameters below, reseting hurts a bit but leaving | 164 | * to the parameters below, reseting hurts a bit but leaving |
@@ -173,10 +174,14 @@ static inline void red_set_parms(struct red_parms *p, | |||
173 | if (delta < 0) | 174 | if (delta < 0) |
174 | delta = 1; | 175 | delta = 1; |
175 | p->qth_delta = delta; | 176 | p->qth_delta = delta; |
176 | p->max_P = red_maxp(Plog); | 177 | if (!max_P) { |
177 | p->max_P *= delta; /* max_P = (qth_max-qth_min)/2^Plog */ | 178 | max_P = red_maxp(Plog); |
178 | 179 | max_P *= delta; /* max_P = (qth_max - qth_min)/2^Plog */ | |
179 | p->max_P_reciprocal = reciprocal_value(p->max_P / delta); | 180 | } |
181 | p->max_P = max_P; | ||
182 | max_p_delta = max_P / delta; | ||
183 | max_p_delta = max(max_p_delta, 1U); | ||
184 | p->max_P_reciprocal = reciprocal_value(max_p_delta); | ||
180 | 185 | ||
181 | /* RED Adaptative target : | 186 | /* RED Adaptative target : |
182 | * [min_th + 0.4*(min_th - max_th), | 187 | * [min_th + 0.4*(min_th - max_th), |
@@ -380,6 +385,7 @@ static inline void red_adaptative_algo(struct red_parms *p) | |||
380 | p->max_P = (p->max_P/10)*9; /* maxp = maxp * Beta */ | 385 | p->max_P = (p->max_P/10)*9; /* maxp = maxp * Beta */ |
381 | 386 | ||
382 | max_p_delta = DIV_ROUND_CLOSEST(p->max_P, p->qth_delta); | 387 | max_p_delta = DIV_ROUND_CLOSEST(p->max_P, p->qth_delta); |
388 | max_p_delta = max(max_p_delta, 1U); | ||
383 | p->max_P_reciprocal = reciprocal_value(max_p_delta); | 389 | p->max_P_reciprocal = reciprocal_value(max_p_delta); |
384 | } | 390 | } |
385 | #endif | 391 | #endif |
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 205d369a217c..bef00acb8bd2 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c | |||
@@ -394,6 +394,7 @@ static void choke_reset(struct Qdisc *sch) | |||
394 | static const struct nla_policy choke_policy[TCA_CHOKE_MAX + 1] = { | 394 | static const struct nla_policy choke_policy[TCA_CHOKE_MAX + 1] = { |
395 | [TCA_CHOKE_PARMS] = { .len = sizeof(struct tc_red_qopt) }, | 395 | [TCA_CHOKE_PARMS] = { .len = sizeof(struct tc_red_qopt) }, |
396 | [TCA_CHOKE_STAB] = { .len = RED_STAB_SIZE }, | 396 | [TCA_CHOKE_STAB] = { .len = RED_STAB_SIZE }, |
397 | [TCA_CHOKE_MAX_P] = { .type = NLA_U32 }, | ||
397 | }; | 398 | }; |
398 | 399 | ||
399 | 400 | ||
@@ -415,6 +416,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt) | |||
415 | int err; | 416 | int err; |
416 | struct sk_buff **old = NULL; | 417 | struct sk_buff **old = NULL; |
417 | unsigned int mask; | 418 | unsigned int mask; |
419 | u32 max_P; | ||
418 | 420 | ||
419 | if (opt == NULL) | 421 | if (opt == NULL) |
420 | return -EINVAL; | 422 | return -EINVAL; |
@@ -427,6 +429,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt) | |||
427 | tb[TCA_CHOKE_STAB] == NULL) | 429 | tb[TCA_CHOKE_STAB] == NULL) |
428 | return -EINVAL; | 430 | return -EINVAL; |
429 | 431 | ||
432 | max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0; | ||
433 | |||
430 | ctl = nla_data(tb[TCA_CHOKE_PARMS]); | 434 | ctl = nla_data(tb[TCA_CHOKE_PARMS]); |
431 | 435 | ||
432 | if (ctl->limit > CHOKE_MAX_QUEUE) | 436 | if (ctl->limit > CHOKE_MAX_QUEUE) |
@@ -476,7 +480,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt) | |||
476 | 480 | ||
477 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, | 481 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, |
478 | ctl->Plog, ctl->Scell_log, | 482 | ctl->Plog, ctl->Scell_log, |
479 | nla_data(tb[TCA_CHOKE_STAB])); | 483 | nla_data(tb[TCA_CHOKE_STAB]), |
484 | max_P); | ||
480 | 485 | ||
481 | if (q->head == q->tail) | 486 | if (q->head == q->tail) |
482 | red_end_of_idle_period(&q->parms); | 487 | red_end_of_idle_period(&q->parms); |
@@ -510,6 +515,7 @@ static int choke_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
510 | goto nla_put_failure; | 515 | goto nla_put_failure; |
511 | 516 | ||
512 | NLA_PUT(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt); | 517 | NLA_PUT(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt); |
518 | NLA_PUT_U32(skb, TCA_CHOKE_MAX_P, q->parms.max_P); | ||
513 | return nla_nest_end(skb, opts); | 519 | return nla_nest_end(skb, opts); |
514 | 520 | ||
515 | nla_put_failure: | 521 | nla_put_failure: |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index b9493a09a870..a1b7407ac2a4 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -34,7 +34,7 @@ struct gred_sched; | |||
34 | 34 | ||
35 | struct gred_sched_data { | 35 | struct gred_sched_data { |
36 | u32 limit; /* HARD maximal queue length */ | 36 | u32 limit; /* HARD maximal queue length */ |
37 | u32 DP; /* the drop pramaters */ | 37 | u32 DP; /* the drop parameters */ |
38 | u32 bytesin; /* bytes seen on virtualQ so far*/ | 38 | u32 bytesin; /* bytes seen on virtualQ so far*/ |
39 | u32 packetsin; /* packets seen on virtualQ so far*/ | 39 | u32 packetsin; /* packets seen on virtualQ so far*/ |
40 | u32 backlog; /* bytes on the virtualQ */ | 40 | u32 backlog; /* bytes on the virtualQ */ |
@@ -379,7 +379,8 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps) | |||
379 | } | 379 | } |
380 | 380 | ||
381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, | 381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, |
382 | struct tc_gred_qopt *ctl, int prio, u8 *stab) | 382 | struct tc_gred_qopt *ctl, int prio, |
383 | u8 *stab, u32 max_P) | ||
383 | { | 384 | { |
384 | struct gred_sched *table = qdisc_priv(sch); | 385 | struct gred_sched *table = qdisc_priv(sch); |
385 | struct gred_sched_data *q; | 386 | struct gred_sched_data *q; |
@@ -400,7 +401,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, | |||
400 | 401 | ||
401 | red_set_parms(&q->parms, | 402 | red_set_parms(&q->parms, |
402 | ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, | 403 | ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, |
403 | ctl->Scell_log, stab); | 404 | ctl->Scell_log, stab, max_P); |
404 | 405 | ||
405 | return 0; | 406 | return 0; |
406 | } | 407 | } |
@@ -409,6 +410,7 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = { | |||
409 | [TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) }, | 410 | [TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) }, |
410 | [TCA_GRED_STAB] = { .len = 256 }, | 411 | [TCA_GRED_STAB] = { .len = 256 }, |
411 | [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) }, | 412 | [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) }, |
413 | [TCA_GRED_MAX_P] = { .type = NLA_U32 }, | ||
412 | }; | 414 | }; |
413 | 415 | ||
414 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) | 416 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) |
@@ -418,6 +420,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
418 | struct nlattr *tb[TCA_GRED_MAX + 1]; | 420 | struct nlattr *tb[TCA_GRED_MAX + 1]; |
419 | int err, prio = GRED_DEF_PRIO; | 421 | int err, prio = GRED_DEF_PRIO; |
420 | u8 *stab; | 422 | u8 *stab; |
423 | u32 max_P; | ||
421 | 424 | ||
422 | if (opt == NULL) | 425 | if (opt == NULL) |
423 | return -EINVAL; | 426 | return -EINVAL; |
@@ -433,6 +436,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
433 | tb[TCA_GRED_STAB] == NULL) | 436 | tb[TCA_GRED_STAB] == NULL) |
434 | return -EINVAL; | 437 | return -EINVAL; |
435 | 438 | ||
439 | max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0; | ||
440 | |||
436 | err = -EINVAL; | 441 | err = -EINVAL; |
437 | ctl = nla_data(tb[TCA_GRED_PARMS]); | 442 | ctl = nla_data(tb[TCA_GRED_PARMS]); |
438 | stab = nla_data(tb[TCA_GRED_STAB]); | 443 | stab = nla_data(tb[TCA_GRED_STAB]); |
@@ -457,7 +462,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
457 | 462 | ||
458 | sch_tree_lock(sch); | 463 | sch_tree_lock(sch); |
459 | 464 | ||
460 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab); | 465 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P); |
461 | if (err < 0) | 466 | if (err < 0) |
462 | goto errout_locked; | 467 | goto errout_locked; |
463 | 468 | ||
@@ -498,6 +503,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
498 | struct gred_sched *table = qdisc_priv(sch); | 503 | struct gred_sched *table = qdisc_priv(sch); |
499 | struct nlattr *parms, *opts = NULL; | 504 | struct nlattr *parms, *opts = NULL; |
500 | int i; | 505 | int i; |
506 | u32 max_p[MAX_DPs]; | ||
501 | struct tc_gred_sopt sopt = { | 507 | struct tc_gred_sopt sopt = { |
502 | .DPs = table->DPs, | 508 | .DPs = table->DPs, |
503 | .def_DP = table->def, | 509 | .def_DP = table->def, |
@@ -509,6 +515,14 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
509 | if (opts == NULL) | 515 | if (opts == NULL) |
510 | goto nla_put_failure; | 516 | goto nla_put_failure; |
511 | NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt); | 517 | NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt); |
518 | |||
519 | for (i = 0; i < MAX_DPs; i++) { | ||
520 | struct gred_sched_data *q = table->tab[i]; | ||
521 | |||
522 | max_p[i] = q ? q->parms.max_P : 0; | ||
523 | } | ||
524 | NLA_PUT(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p); | ||
525 | |||
512 | parms = nla_nest_start(skb, TCA_GRED_PARMS); | 526 | parms = nla_nest_start(skb, TCA_GRED_PARMS); |
513 | if (parms == NULL) | 527 | if (parms == NULL) |
514 | goto nla_put_failure; | 528 | goto nla_put_failure; |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 8f5a85bf9d10..ce2256a17d7e 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -170,6 +170,7 @@ static void red_destroy(struct Qdisc *sch) | |||
170 | static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { | 170 | static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { |
171 | [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) }, | 171 | [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) }, |
172 | [TCA_RED_STAB] = { .len = RED_STAB_SIZE }, | 172 | [TCA_RED_STAB] = { .len = RED_STAB_SIZE }, |
173 | [TCA_RED_MAX_P] = { .type = NLA_U32 }, | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | static int red_change(struct Qdisc *sch, struct nlattr *opt) | 176 | static int red_change(struct Qdisc *sch, struct nlattr *opt) |
@@ -179,6 +180,7 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
179 | struct tc_red_qopt *ctl; | 180 | struct tc_red_qopt *ctl; |
180 | struct Qdisc *child = NULL; | 181 | struct Qdisc *child = NULL; |
181 | int err; | 182 | int err; |
183 | u32 max_P; | ||
182 | 184 | ||
183 | if (opt == NULL) | 185 | if (opt == NULL) |
184 | return -EINVAL; | 186 | return -EINVAL; |
@@ -191,6 +193,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
191 | tb[TCA_RED_STAB] == NULL) | 193 | tb[TCA_RED_STAB] == NULL) |
192 | return -EINVAL; | 194 | return -EINVAL; |
193 | 195 | ||
196 | max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; | ||
197 | |||
194 | ctl = nla_data(tb[TCA_RED_PARMS]); | 198 | ctl = nla_data(tb[TCA_RED_PARMS]); |
195 | 199 | ||
196 | if (ctl->limit > 0) { | 200 | if (ctl->limit > 0) { |
@@ -209,8 +213,9 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
209 | } | 213 | } |
210 | 214 | ||
211 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, | 215 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, |
212 | ctl->Plog, ctl->Scell_log, | 216 | ctl->Plog, ctl->Scell_log, |
213 | nla_data(tb[TCA_RED_STAB])); | 217 | nla_data(tb[TCA_RED_STAB]), |
218 | max_P); | ||
214 | 219 | ||
215 | del_timer(&q->adapt_timer); | 220 | del_timer(&q->adapt_timer); |
216 | if (ctl->flags & TC_RED_ADAPTATIVE) | 221 | if (ctl->flags & TC_RED_ADAPTATIVE) |