These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / net / sched / sch_gred.c
index 634529e..8010510 100644 (file)
@@ -165,7 +165,8 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                         * if no default DP has been configured. This
                         * allows for DP flows to be left untouched.
                         */
-                       if (skb_queue_len(&sch->q) < qdisc_dev(sch)->tx_queue_len)
+                       if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <=
+                                       sch->limit))
                                return qdisc_enqueue_tail(skb, sch);
                        else
                                goto drop;
@@ -397,7 +398,10 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
 
        q->DP = dp;
        q->prio = prio;
-       q->limit = ctl->limit;
+       if (ctl->limit > sch->limit)
+               q->limit = sch->limit;
+       else
+               q->limit = ctl->limit;
 
        if (q->backlog == 0)
                red_end_of_idle_period(&q->vars);
@@ -414,6 +418,7 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = {
        [TCA_GRED_STAB]         = { .len = 256 },
        [TCA_GRED_DPS]          = { .len = sizeof(struct tc_gred_sopt) },
        [TCA_GRED_MAX_P]        = { .type = NLA_U32 },
+       [TCA_GRED_LIMIT]        = { .type = NLA_U32 },
 };
 
 static int gred_change(struct Qdisc *sch, struct nlattr *opt)
@@ -433,11 +438,15 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
        if (err < 0)
                return err;
 
-       if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL)
+       if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL) {
+               if (tb[TCA_GRED_LIMIT] != NULL)
+                       sch->limit = nla_get_u32(tb[TCA_GRED_LIMIT]);
                return gred_change_table_def(sch, opt);
+       }
 
        if (tb[TCA_GRED_PARMS] == NULL ||
-           tb[TCA_GRED_STAB] == NULL)
+           tb[TCA_GRED_STAB] == NULL ||
+           tb[TCA_GRED_LIMIT] != NULL)
                return -EINVAL;
 
        max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0;
@@ -501,6 +510,12 @@ static int gred_init(struct Qdisc *sch, struct nlattr *opt)
        if (tb[TCA_GRED_PARMS] || tb[TCA_GRED_STAB])
                return -EINVAL;
 
+       if (tb[TCA_GRED_LIMIT])
+               sch->limit = nla_get_u32(tb[TCA_GRED_LIMIT]);
+       else
+               sch->limit = qdisc_dev(sch)->tx_queue_len
+                            * psched_mtu(qdisc_dev(sch));
+
        return gred_change_table_def(sch, tb[TCA_GRED_DPS]);
 }
 
@@ -531,6 +546,9 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
        if (nla_put(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p))
                goto nla_put_failure;
 
+       if (nla_put_u32(skb, TCA_GRED_LIMIT, sch->limit))
+               goto nla_put_failure;
+
        parms = nla_nest_start(skb, TCA_GRED_PARMS);
        if (parms == NULL)
                goto nla_put_failure;