History

net_sched: tbf: support of 64bit rates

With psched_ratecfg_precompute(), tbf can deal with 64bit rates. Add two new attributes so that tc can use them to break the 32bit limit.

Yang Yingliang committed 13 years ago

Commit a33c4a21 parent 51f37732 files · +20 −4Browse files

Unified · Split

2 files
  1. include/uapi/linux/pkt_sched.h +2 −0
  2. net/sched/sch_tbf.c +18 −4
include/uapi/linux/pkt_sched.h+2−0
@@ -171,6 +171,8 @@ enum { · 170 unmodified lines
171171 TCA_TBF_PARMS,
172172 TCA_TBF_RTAB,
173173 TCA_TBF_PTAB,
174+ TCA_TBF_RATE64,
175+ TCA_TBF_PRATE64,
174176 __TCA_TBF_MAX,
175177 };
176178
net/sched/sch_tbf.c+18−4
@@ -266,20 +266,23 @@ static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = { · 265 unmodified lines
266266 [TCA_TBF_PARMS] = { .len = sizeof(struct tc_tbf_qopt) },
267267 [TCA_TBF_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
268268 [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
269+ [TCA_TBF_RATE64] = { .type = NLA_U64 },
270+ [TCA_TBF_PRATE64] = { .type = NLA_U64 },
269271 };
270272
271273 static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
272274 {
273275 int err;
274276 struct tbf_sched_data *q = qdisc_priv(sch);
275− struct nlattr *tb[TCA_TBF_PTAB + 1];
277+ struct nlattr *tb[TCA_TBF_MAX + 1];
276278 struct tc_tbf_qopt *qopt;
277279 struct qdisc_rate_table *rtab = NULL;
278280 struct qdisc_rate_table *ptab = NULL;
279281 struct Qdisc *child = NULL;
280282 int max_size, n;
283+ u64 rate64 = 0, prate64 = 0;
281284
282− err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, tbf_policy);
285+ err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy);
283286 if (err < 0)
284287 return err;
285288
@@ -341,9 +344,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) · 55 unmodified lines
341344 q->tokens = q->buffer;
342345 q->ptokens = q->mtu;
343346
344− psched_ratecfg_precompute(&q->rate, &rtab->rate, 0);
347+ if (tb[TCA_TBF_RATE64])
348+ rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
349+ psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64);
345350 if (ptab) {
346− psched_ratecfg_precompute(&q->peak, &ptab->rate, 0);
351+ if (tb[TCA_TBF_PRATE64])
352+ prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
353+ psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64);
347354 q->peak_present = true;
348355 } else {
349356 q->peak_present = false;
@@ -402,6 +409,13 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) · 52 unmodified lines
402409 opt.buffer = PSCHED_NS2TICKS(q->buffer);
403410 if (nla_put(skb, TCA_TBF_PARMS, sizeof(opt), &opt))
404411 goto nla_put_failure;
412+ if (q->rate.rate_bytes_ps >= (1ULL << 32) &&
413+ nla_put_u64(skb, TCA_TBF_RATE64, q->rate.rate_bytes_ps))
414+ goto nla_put_failure;
415+ if (q->peak_present &&
416+ q->peak.rate_bytes_ps >= (1ULL << 32) &&
417+ nla_put_u64(skb, TCA_TBF_PRATE64, q->peak.rate_bytes_ps))
418+ goto nla_put_failure;
405419
406420 nla_nest_end(skb, nest);
407421 return skb->len;