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