aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2013-11-07 21:23:34 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-09 14:53:37 -0500
commita33c4a2663c19ac01e557d6b78806271eec2a150 (patch)
treedc5627e103416512e31b0fc628c836572b8f66f1 /net
parent51f3773bdeecf6ec48647dbfea335be4e507da0b (diff)
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. Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Suggested-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sched/sch_tbf.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index b0571224f3c9..68f98595819c 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -266,20 +266,23 @@ static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = {
266 [TCA_TBF_PARMS] = { .len = sizeof(struct tc_tbf_qopt) }, 266 [TCA_TBF_PARMS] = { .len = sizeof(struct tc_tbf_qopt) },
267 [TCA_TBF_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, 267 [TCA_TBF_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
268 [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, 268 [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
269 [TCA_TBF_RATE64] = { .type = NLA_U64 },
270 [TCA_TBF_PRATE64] = { .type = NLA_U64 },
269}; 271};
270 272
271static int tbf_change(struct Qdisc *sch, struct nlattr *opt) 273static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
272{ 274{
273 int err; 275 int err;
274 struct tbf_sched_data *q = qdisc_priv(sch); 276 struct tbf_sched_data *q = qdisc_priv(sch);
275 struct nlattr *tb[TCA_TBF_PTAB + 1]; 277 struct nlattr *tb[TCA_TBF_MAX + 1];
276 struct tc_tbf_qopt *qopt; 278 struct tc_tbf_qopt *qopt;
277 struct qdisc_rate_table *rtab = NULL; 279 struct qdisc_rate_table *rtab = NULL;
278 struct qdisc_rate_table *ptab = NULL; 280 struct qdisc_rate_table *ptab = NULL;
279 struct Qdisc *child = NULL; 281 struct Qdisc *child = NULL;
280 int max_size, n; 282 int max_size, n;
283 u64 rate64 = 0, prate64 = 0;
281 284
282 err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, tbf_policy); 285 err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy);
283 if (err < 0) 286 if (err < 0)
284 return err; 287 return err;
285 288
@@ -341,9 +344,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
341 q->tokens = q->buffer; 344 q->tokens = q->buffer;
342 q->ptokens = q->mtu; 345 q->ptokens = q->mtu;
343 346
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);
345 if (ptab) { 350 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);
347 q->peak_present = true; 354 q->peak_present = true;
348 } else { 355 } else {
349 q->peak_present = false; 356 q->peak_present = false;
@@ -402,6 +409,13 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
402 opt.buffer = PSCHED_NS2TICKS(q->buffer); 409 opt.buffer = PSCHED_NS2TICKS(q->buffer);
403 if (nla_put(skb, TCA_TBF_PARMS, sizeof(opt), &opt)) 410 if (nla_put(skb, TCA_TBF_PARMS, sizeof(opt), &opt))
404 goto nla_put_failure; 411 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;
405 419
406 nla_nest_end(skb, nest); 420 nla_nest_end(skb, nest);
407 return skb->len; 421 return skb->len;