Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / net / sched / sch_tbf.c
index 4f505a006896578ebdac1392af1dc064500665c9..a4afde14e8656cca6c0688bc2d092334edaf69df 100644 (file)
 struct tbf_sched_data {
 /* Parameters */
        u32             limit;          /* Maximal length of backlog: bytes */
+       u32             max_size;
        s64             buffer;         /* Token bucket depth/rate: MUST BE >= MTU/B */
        s64             mtu;
-       u32             max_size;
        struct psched_ratecfg rate;
        struct psched_ratecfg peak;
-       bool peak_present;
 
 /* Variables */
        s64     tokens;                 /* Current number of B tokens */
@@ -176,7 +175,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch)
                ret = qdisc_enqueue(segs, q->qdisc);
                if (ret != NET_XMIT_SUCCESS) {
                        if (net_xmit_drop_count(ret))
-                               sch->qstats.drops++;
+                               qdisc_qstats_drop(sch);
                } else {
                        nb++;
                }
@@ -202,7 +201,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        ret = qdisc_enqueue(skb, q->qdisc);
        if (ret != NET_XMIT_SUCCESS) {
                if (net_xmit_drop_count(ret))
-                       sch->qstats.drops++;
+                       qdisc_qstats_drop(sch);
                return ret;
        }
 
@@ -217,11 +216,16 @@ static unsigned int tbf_drop(struct Qdisc *sch)
 
        if (q->qdisc->ops->drop && (len = q->qdisc->ops->drop(q->qdisc)) != 0) {
                sch->q.qlen--;
-               sch->qstats.drops++;
+               qdisc_qstats_drop(sch);
        }
        return len;
 }
 
+static bool tbf_peak_present(const struct tbf_sched_data *q)
+{
+       return q->peak.rate_bytes_ps;
+}
+
 static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
 {
        struct tbf_sched_data *q = qdisc_priv(sch);
@@ -235,10 +239,10 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
                s64 ptoks = 0;
                unsigned int len = qdisc_pkt_len(skb);
 
-               now = ktime_to_ns(ktime_get());
+               now = ktime_get_ns();
                toks = min_t(s64, now - q->t_c, q->buffer);
 
-               if (q->peak_present) {
+               if (tbf_peak_present(q)) {
                        ptoks = toks + q->ptokens;
                        if (ptoks > q->mtu)
                                ptoks = q->mtu;
@@ -264,7 +268,8 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
                }
 
                qdisc_watchdog_schedule_ns(&q->watchdog,
-                                          now + max_t(long, -toks, -ptoks));
+                                          now + max_t(long, -toks, -ptoks),
+                                          true);
 
                /* Maybe we have a shorter packet in the queue,
                   which can be sent now. It sounds cool,
@@ -277,7 +282,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
                   (cf. CSZ, HPFQ, HFSC)
                 */
 
-               sch->qstats.overlimits++;
+               qdisc_qstats_overlimit(sch);
        }
        return NULL;
 }
@@ -288,7 +293,7 @@ static void tbf_reset(struct Qdisc *sch)
 
        qdisc_reset(q->qdisc);
        sch->q.qlen = 0;
-       q->t_c = ktime_to_ns(ktime_get());
+       q->t_c = ktime_get_ns();
        q->tokens = q->buffer;
        q->ptokens = q->mtu;
        qdisc_watchdog_cancel(&q->watchdog);
@@ -366,6 +371,8 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
                } else {
                        max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu));
                }
+       } else {
+               memset(&peak, 0, sizeof(peak));
        }
 
        if (max_size < psched_mtu(qdisc_dev(sch)))
@@ -410,12 +417,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        q->ptokens = q->mtu;
 
        memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg));
-       if (qopt->peakrate.rate) {
-               memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
-               q->peak_present = true;
-       } else {
-               q->peak_present = false;
-       }
+       memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
 
        sch_tree_unlock(sch);
        err = 0;
@@ -430,7 +432,7 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt)
        if (opt == NULL)
                return -EINVAL;
 
-       q->t_c = ktime_to_ns(ktime_get());
+       q->t_c = ktime_get_ns();
        qdisc_watchdog_init(&q->watchdog, sch);
        q->qdisc = &noop_qdisc;
 
@@ -458,7 +460,7 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
 
        opt.limit = q->limit;
        psched_ratecfg_getrate(&opt.rate, &q->rate);
-       if (q->peak_present)
+       if (tbf_peak_present(q))
                psched_ratecfg_getrate(&opt.peakrate, &q->peak);
        else
                memset(&opt.peakrate, 0, sizeof(opt.peakrate));
@@ -469,13 +471,12 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
        if (q->rate.rate_bytes_ps >= (1ULL << 32) &&
            nla_put_u64(skb, TCA_TBF_RATE64, q->rate.rate_bytes_ps))
                goto nla_put_failure;
-       if (q->peak_present &&
+       if (tbf_peak_present(q) &&
            q->peak.rate_bytes_ps >= (1ULL << 32) &&
            nla_put_u64(skb, TCA_TBF_PRATE64, q->peak.rate_bytes_ps))
                goto nla_put_failure;
 
-       nla_nest_end(skb, nest);
-       return skb->len;
+       return nla_nest_end(skb, nest);
 
 nla_put_failure:
        nla_nest_cancel(skb, nest);