sch_cake: Correctly update parent qlen when splitting GSO packets
authorToke Høiland-Jørgensen <toke@redhat.com>
Wed, 9 Jan 2019 16:09:44 +0000 (17:09 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Jan 2019 04:12:01 +0000 (20:12 -0800)
To ensure parent qdiscs have the same notion of the number of enqueued
packets even after splitting a GSO packet, update the qdisc tree with the
number of packets that was added due to the split.

Reported-by: Pete Heist <pete@heistp.net>
Tested-by: Pete Heist <pete@heistp.net>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/sch_cake.c

index b910cd5c56f7434cd34decec7d521479e77f441f..73940293700d7a56507d1b35fd8a2a05c2ba945e 100644 (file)
@@ -1667,7 +1667,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))
@@ -1683,6 +1683,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                        flow_queue_add(flow, segs);
 
                        sch->q.qlen++;
+                       numsegs++;
                        slen += segs->len;
                        q->buffer_used += segs->truesize;
                        b->packets++;
@@ -1696,7 +1697,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, 1len);
+               qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
                consume_skb(skb);
        } else {
                /* not splitting */