aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/pkt_sched.h2
-rw-r--r--include/net/red.h16
-rw-r--r--net/sched/sch_choke.c8
-rw-r--r--net/sched/sch_gred.c22
-rw-r--r--net/sched/sch_red.c9
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
156static inline void red_set_parms(struct red_parms *p, 156static 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)
394static const struct nla_policy choke_policy[TCA_CHOKE_MAX + 1] = { 394static 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
515nla_put_failure: 521nla_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
35struct gred_sched_data { 35struct 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
381static inline int gred_change_vq(struct Qdisc *sch, int dp, 381static 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
414static int gred_change(struct Qdisc *sch, struct nlattr *opt) 416static 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)
170static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { 170static 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
175static int red_change(struct Qdisc *sch, struct nlattr *opt) 176static 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)