Pete Heist <p...@heistp.net> writes:

>> On Jan 4, 2019, at 11:34 PM, Toke Høiland-Jørgensen <t...@toke.dk> wrote:
>> 
>> Pete Heist <p...@heistp.net> writes:
>> 
>> This basically means that we can't use CAKE as a leaf qdisc with GSO
>> splitting as it stands currently. I *think* the solution is for CAKE to
>> notify its parents; could you try the patch below and see if it helps?
>
> Aha, good news. :)
>
> I’m probably not currently in a position to try it on my old kernels with the 
> out of tree build:
>
> On 3.16.7:

Hmm, try this version for 3.16 - probably doesn't work on later kernels.
I'll look into a proper backport once you've confirmed that it works :)

-Toke

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index b910cd5c56f7..ef3acdbb8429 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1617,6 +1617,44 @@ static u32 cake_classify(struct Qdisc *sch, struct 
cake_tin_data **t,
 
 static void cake_reconfigure(struct Qdisc *sch);
 
+
+static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
+{
+       struct Qdisc *q;
+
+       if (!(root->flags & TCQ_F_BUILTIN) &&
+           root->handle == handle)
+               return root;
+
+       list_for_each_entry(q, &root->list, list) {
+               if (q->handle == handle)
+                       return q;
+       }
+       return NULL;
+}
+
+void adjust_parent_qlen(struct Qdisc *sch, unsigned int n,
+                              unsigned int len)
+{
+       u32 parentid;
+       if (n == 0 && len == 0)
+               return;
+       rcu_read_lock();
+       while ((parentid = sch->parent)) {
+               if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
+                       break;
+
+               sch = qdisc_match_from_root(qdisc_dev(sch), TC_H_MAJ(parentid));
+               if (sch == NULL) {
+                       WARN_ON_ONCE(parentid != TC_H_ROOT);
+                       break;
+               }
+               sch->q.qlen += n;
+               sch->qstats.backlog += len;
+       }
+       rcu_read_unlock();
+}
+
 static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                        struct sk_buff **to_free)
 {
@@ -1667,7 +1705,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
        if (skb_is_gso(skb) && q->rate_flags & CAKE_FLAG_SPLIT_GSO) {
                struct sk_buff *segs, *nskb;
                netdev_features_t features = netif_skb_features(skb);
-               unsigned int slen = 0;
+               unsigned int slen = 0, numsegs = 0;
 
                segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
                if (IS_ERR_OR_NULL(segs))
@@ -1684,6 +1722,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
 
                        sch->q.qlen++;
                        slen += segs->len;
+                       numsegs++;
                        q->buffer_used += segs->truesize;
                        b->packets++;
                        segs = nskb;
@@ -1696,7 +1735,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
                sch->qstats.backlog += slen;
                q->avg_window_bytes += slen;
 
-               qdisc_tree_reduce_backlog(sch, 1, len);
+               adjust_parent_qlen(sch, numsegs - 1, slen - len);
                consume_skb(skb);
        } else {
                /* not splitting */
_______________________________________________
Cake mailing list
Cake@lists.bufferbloat.net
https://lists.bufferbloat.net/listinfo/cake

Reply via email to