aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2013-12-19 20:24:47 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-26 13:54:22 -0500
commit2e04ad424b03661ec8239acd52146497eb33be1c (patch)
treeddc00646275400d740323a8753a02b7177e0d544 /net/sched
parent4e2d52bfb2e954902b844a300fdba53d5ebb0905 (diff)
sch_tbf: add TBF_BURST/TBF_PBURST attribute
When we set burst to 1514 with low rate in userspace, the kernel get a value of burst that less than 1514, which doesn't work. Because it may make some loss when transform burst to buffer in userspace. This makes burst lose some bytes, when the kernel transform the buffer back to burst. This patch adds two new attributes to support sending burst/mtu to kernel directly to avoid the loss. Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_tbf.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 887e672f9d7d..fbba5b0ec121 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -307,6 +307,8 @@ static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = {
307 [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, 307 [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
308 [TCA_TBF_RATE64] = { .type = NLA_U64 }, 308 [TCA_TBF_RATE64] = { .type = NLA_U64 },
309 [TCA_TBF_PRATE64] = { .type = NLA_U64 }, 309 [TCA_TBF_PRATE64] = { .type = NLA_U64 },
310 [TCA_TBF_BURST] = { .type = NLA_U32 },
311 [TCA_TBF_PBURST] = { .type = NLA_U32 },
310}; 312};
311 313
312static int tbf_change(struct Qdisc *sch, struct nlattr *opt) 314static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
@@ -358,7 +360,12 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
358 rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); 360 rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
359 psched_ratecfg_precompute(&rate, &qopt->rate, rate64); 361 psched_ratecfg_precompute(&rate, &qopt->rate, rate64);
360 362
361 max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U); 363 if (tb[TCA_TBF_BURST]) {
364 max_size = nla_get_u32(tb[TCA_TBF_BURST]);
365 buffer = psched_l2t_ns(&rate, max_size);
366 } else {
367 max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U);
368 }
362 369
363 if (qopt->peakrate.rate) { 370 if (qopt->peakrate.rate) {
364 if (tb[TCA_TBF_PRATE64]) 371 if (tb[TCA_TBF_PRATE64])
@@ -366,12 +373,18 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
366 psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64); 373 psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64);
367 if (peak.rate_bytes_ps <= rate.rate_bytes_ps) { 374 if (peak.rate_bytes_ps <= rate.rate_bytes_ps) {
368 pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n", 375 pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n",
369 peak.rate_bytes_ps, rate.rate_bytes_ps); 376 peak.rate_bytes_ps, rate.rate_bytes_ps);
370 err = -EINVAL; 377 err = -EINVAL;
371 goto done; 378 goto done;
372 } 379 }
373 380
374 max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu)); 381 if (tb[TCA_TBF_PBURST]) {
382 u32 pburst = nla_get_u32(tb[TCA_TBF_PBURST]);
383 max_size = min_t(u32, max_size, pburst);
384 mtu = psched_l2t_ns(&peak, pburst);
385 } else {
386 max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu));
387 }
375 } 388 }
376 389
377 if (max_size < psched_mtu(qdisc_dev(sch))) 390 if (max_size < psched_mtu(qdisc_dev(sch)))
@@ -391,9 +404,15 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
391 q->qdisc = child; 404 q->qdisc = child;
392 } 405 }
393 q->limit = qopt->limit; 406 q->limit = qopt->limit;
394 q->mtu = PSCHED_TICKS2NS(qopt->mtu); 407 if (tb[TCA_TBF_PBURST])
408 q->mtu = mtu;
409 else
410 q->mtu = PSCHED_TICKS2NS(qopt->mtu);
395 q->max_size = max_size; 411 q->max_size = max_size;
396 q->buffer = PSCHED_TICKS2NS(qopt->buffer); 412 if (tb[TCA_TBF_BURST])
413 q->buffer = buffer;
414 else
415 q->buffer = PSCHED_TICKS2NS(qopt->buffer);
397 q->tokens = q->buffer; 416 q->tokens = q->buffer;
398 q->ptokens = q->mtu; 417 q->ptokens = q->mtu;
399 418