]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net_sched: use qdisc_dequeue_drop() in cake, codel, fq_codel
authorEric Dumazet <edumazet@google.com>
Fri, 21 Nov 2025 08:32:56 +0000 (08:32 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 25 Nov 2025 15:10:32 +0000 (16:10 +0100)
cake, codel and fq_codel can drop many packets from dequeue().

Use qdisc_dequeue_drop() so that the freeing can happen
outside of the qdisc spinlock scope.

Add TCQ_F_DEQUEUE_DROPS to sch->flags.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20251121083256.674562-15-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/sched/sch_cake.c
net/sched/sch_codel.c
net/sched/sch_fq_codel.c

index 5948a149129c6de041ba949e2e2b5b6b4eb54166..0ea9440f68c60ab69e9dd889b225c1a171199787 100644 (file)
@@ -2183,7 +2183,7 @@ retry:
                b->tin_dropped++;
                qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb));
                qdisc_qstats_drop(sch);
-               kfree_skb_reason(skb, reason);
+               qdisc_dequeue_drop(sch, skb, reason);
                if (q->rate_flags & CAKE_FLAG_INGRESS)
                        goto retry;
        }
@@ -2724,6 +2724,8 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
        int i, j, err;
 
        sch->limit = 10240;
+       sch->flags |= TCQ_F_DEQUEUE_DROPS;
+
        q->tin_mode = CAKE_DIFFSERV_DIFFSERV3;
        q->flow_mode  = CAKE_FLOW_TRIPLE;
 
index fa0314679e434a4f84a128e8330bb92743c3d66a..c6551578f1cf8d332ca20ea062e858ffb437966a 100644 (file)
@@ -52,7 +52,7 @@ static void drop_func(struct sk_buff *skb, void *ctx)
 {
        struct Qdisc *sch = ctx;
 
-       kfree_skb_reason(skb, SKB_DROP_REASON_QDISC_CONGESTED);
+       qdisc_dequeue_drop(sch, skb, SKB_DROP_REASON_QDISC_CONGESTED);
        qdisc_qstats_drop(sch);
 }
 
@@ -182,6 +182,8 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt,
        else
                sch->flags &= ~TCQ_F_CAN_BYPASS;
 
+       sch->flags |= TCQ_F_DEQUEUE_DROPS;
+
        return 0;
 }
 
index a141423929394d7ebe127aa328dcf13ae67b3d56..dc187c7f06b10d8fd4191ead82e6a60133fff09d 100644 (file)
@@ -275,7 +275,7 @@ static void drop_func(struct sk_buff *skb, void *ctx)
 {
        struct Qdisc *sch = ctx;
 
-       kfree_skb_reason(skb, SKB_DROP_REASON_QDISC_CONGESTED);
+       qdisc_dequeue_drop(sch, skb, SKB_DROP_REASON_QDISC_CONGESTED);
        qdisc_qstats_drop(sch);
 }
 
@@ -519,6 +519,9 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
                sch->flags |= TCQ_F_CAN_BYPASS;
        else
                sch->flags &= ~TCQ_F_CAN_BYPASS;
+
+       sch->flags |= TCQ_F_DEQUEUE_DROPS;
+
        return 0;
 
 alloc_failure: