Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352421
b: refs/heads/master
c: b757c93
h: refs/heads/master
i:
  352419: 089da9a
v: v3
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Feb 12, 2013
1 parent e3df8a0 commit 8caf86c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 34c5d292ce05d2bf52e692c44292b0ababba2853
refs/heads/master: b757c9336d63f94c6b57532bb4e8651d8b28786f
76 changes: 37 additions & 39 deletions trunk/net/sched/sch_tbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/netlink.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>


Expand Down Expand Up @@ -100,23 +101,21 @@
struct tbf_sched_data {
/* Parameters */
u32 limit; /* Maximal length of backlog: bytes */
u32 buffer; /* Token bucket depth/rate: MUST BE >= MTU/B */
u32 mtu;
s64 buffer; /* Token bucket depth/rate: MUST BE >= MTU/B */
s64 mtu;
u32 max_size;
struct qdisc_rate_table *R_tab;
struct qdisc_rate_table *P_tab;
struct psched_ratecfg rate;
struct psched_ratecfg peak;
bool peak_present;

/* Variables */
long tokens; /* Current number of B tokens */
long ptokens; /* Current number of P tokens */
psched_time_t t_c; /* Time check-point */
s64 tokens; /* Current number of B tokens */
s64 ptokens; /* Current number of P tokens */
s64 t_c; /* Time check-point */
struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */
struct qdisc_watchdog watchdog; /* Watchdog timer */
};

#define L2T(q, L) qdisc_l2t((q)->R_tab, L)
#define L2T_P(q, L) qdisc_l2t((q)->P_tab, L)

static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct tbf_sched_data *q = qdisc_priv(sch);
Expand Down Expand Up @@ -156,24 +155,24 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
skb = q->qdisc->ops->peek(q->qdisc);

if (skb) {
psched_time_t now;
long toks;
long ptoks = 0;
s64 now;
s64 toks;
s64 ptoks = 0;
unsigned int len = qdisc_pkt_len(skb);

now = psched_get_time();
toks = psched_tdiff_bounded(now, q->t_c, q->buffer);
now = ktime_to_ns(ktime_get());
toks = min_t(s64, now - q->t_c, q->buffer);

if (q->P_tab) {
if (q->peak_present) {
ptoks = toks + q->ptokens;
if (ptoks > (long)q->mtu)
if (ptoks > q->mtu)
ptoks = q->mtu;
ptoks -= L2T_P(q, len);
ptoks -= (s64) psched_l2t_ns(&q->peak, len);
}
toks += q->tokens;
if (toks > (long)q->buffer)
if (toks > q->buffer)
toks = q->buffer;
toks -= L2T(q, len);
toks -= (s64) psched_l2t_ns(&q->rate, len);

if ((toks|ptoks) >= 0) {
skb = qdisc_dequeue_peeked(q->qdisc);
Expand All @@ -189,8 +188,8 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
return skb;
}

qdisc_watchdog_schedule(&q->watchdog,
now + max_t(long, -toks, -ptoks));
qdisc_watchdog_schedule_ns(&q->watchdog,
now + max_t(long, -toks, -ptoks));

/* Maybe we have a shorter packet in the queue,
which can be sent now. It sounds cool,
Expand All @@ -214,7 +213,7 @@ static void tbf_reset(struct Qdisc *sch)

qdisc_reset(q->qdisc);
sch->q.qlen = 0;
q->t_c = psched_get_time();
q->t_c = ktime_to_ns(ktime_get());
q->tokens = q->buffer;
q->ptokens = q->mtu;
qdisc_watchdog_cancel(&q->watchdog);
Expand Down Expand Up @@ -293,14 +292,19 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
q->qdisc = child;
}
q->limit = qopt->limit;
q->mtu = qopt->mtu;
q->mtu = PSCHED_TICKS2NS(qopt->mtu);
q->max_size = max_size;
q->buffer = qopt->buffer;
q->buffer = PSCHED_TICKS2NS(qopt->buffer);
q->tokens = q->buffer;
q->ptokens = q->mtu;

swap(q->R_tab, rtab);
swap(q->P_tab, ptab);
psched_ratecfg_precompute(&q->rate, rtab->rate.rate);
if (ptab) {
psched_ratecfg_precompute(&q->peak, ptab->rate.rate);
q->peak_present = true;
} else {
q->peak_present = false;
}

sch_tree_unlock(sch);
err = 0;
Expand All @@ -319,7 +323,7 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt)
if (opt == NULL)
return -EINVAL;

q->t_c = psched_get_time();
q->t_c = ktime_to_ns(ktime_get());
qdisc_watchdog_init(&q->watchdog, sch);
q->qdisc = &noop_qdisc;

Expand All @@ -331,12 +335,6 @@ static void tbf_destroy(struct Qdisc *sch)
struct tbf_sched_data *q = qdisc_priv(sch);

qdisc_watchdog_cancel(&q->watchdog);

if (q->P_tab)
qdisc_put_rtab(q->P_tab);
if (q->R_tab)
qdisc_put_rtab(q->R_tab);

qdisc_destroy(q->qdisc);
}

Expand All @@ -352,13 +350,13 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
goto nla_put_failure;

opt.limit = q->limit;
opt.rate = q->R_tab->rate;
if (q->P_tab)
opt.peakrate = q->P_tab->rate;
opt.rate.rate = psched_ratecfg_getrate(&q->rate);
if (q->peak_present)
opt.peakrate.rate = psched_ratecfg_getrate(&q->peak);
else
memset(&opt.peakrate, 0, sizeof(opt.peakrate));
opt.mtu = q->mtu;
opt.buffer = q->buffer;
opt.mtu = PSCHED_NS2TICKS(q->mtu);
opt.buffer = PSCHED_NS2TICKS(q->buffer);
if (nla_put(skb, TCA_TBF_PARMS, sizeof(opt), &opt))
goto nla_put_failure;

Expand Down

0 comments on commit 8caf86c

Please sign in to comment.