--- /dev/null
+From df008598b3a00be02a8051fde89ca0fbc416bd55 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:24 -0700
+Subject: sch_drr: make drr_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit df008598b3a00be02a8051fde89ca0fbc416bd55 upstream.
+
+drr_qlen_notify() always deletes the DRR class from its active list
+with list_del(), therefore, it is not idempotent and not friendly
+to its callers, like fq_codel_dequeue().
+
+Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers'
+life. Also change other list_del()'s to list_del_init() just to be
+extra safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-3-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_drr.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/net/sched/sch_drr.c
++++ b/net/sched/sch_drr.c
+@@ -110,6 +110,7 @@ static int drr_change_class(struct Qdisc
+ return -ENOBUFS;
+
+ gnet_stats_basic_sync_init(&cl->bstats);
++ INIT_LIST_HEAD(&cl->alist);
+ cl->common.classid = classid;
+ cl->quantum = quantum;
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue,
+@@ -234,7 +235,7 @@ static void drr_qlen_notify(struct Qdisc
+ {
+ struct drr_class *cl = (struct drr_class *)arg;
+
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+ }
+
+ static int drr_dump_class(struct Qdisc *sch, unsigned long arg,
+@@ -393,7 +394,7 @@ static struct sk_buff *drr_dequeue(struc
+ if (unlikely(skb == NULL))
+ goto out;
+ if (cl->qdisc->q.qlen == 0)
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+
+ bstats_update(&cl->bstats, skb);
+ qdisc_bstats_update(sch, skb);
+@@ -434,7 +435,7 @@ static void drr_reset_qdisc(struct Qdisc
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) {
+ if (cl->qdisc->q.qlen)
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+ qdisc_reset(cl->qdisc);
+ }
+ }
--- /dev/null
+From a7a15f39c682ac4268624da2abdb9114bdde96d5 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:27 -0700
+Subject: sch_ets: make est_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit a7a15f39c682ac4268624da2abdb9114bdde96d5 upstream.
+
+est_qlen_notify() deletes its class from its active list with
+list_del() when qlen is 0, therefore, it is not idempotent and
+not friendly to its callers, like fq_codel_dequeue().
+
+Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers'
+life. Also change other list_del()'s to list_del_init() just to be
+extra safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://patch.msgid.link/20250403211033.166059-6-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_ets.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -298,7 +298,7 @@ static void ets_class_qlen_notify(struct
+ * to remove them.
+ */
+ if (!ets_class_is_strict(q, cl) && sch->q.qlen)
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+ }
+
+ static int ets_class_dump(struct Qdisc *sch, unsigned long arg,
+@@ -491,7 +491,7 @@ static struct sk_buff *ets_qdisc_dequeue
+ if (unlikely(!skb))
+ goto out;
+ if (cl->qdisc->q.qlen == 0)
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+ return ets_qdisc_dequeue_skb(sch, skb);
+ }
+
+@@ -660,7 +660,7 @@ static int ets_qdisc_change(struct Qdisc
+ }
+ for (i = q->nbands; i < oldbands; i++) {
+ if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+- list_del(&q->classes[i].alist);
++ list_del_init(&q->classes[i].alist);
+ qdisc_tree_flush_backlog(q->classes[i].qdisc);
+ }
+ q->nstrict = nstrict;
+@@ -716,7 +716,7 @@ static void ets_qdisc_reset(struct Qdisc
+
+ for (band = q->nstrict; band < q->nbands; band++) {
+ if (q->classes[band].qdisc->q.qlen)
+- list_del(&q->classes[band].alist);
++ list_del_init(&q->classes[band].alist);
+ }
+ for (band = 0; band < q->nbands; band++)
+ qdisc_reset(q->classes[band].qdisc);
--- /dev/null
+From 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:25 -0700
+Subject: sch_hfsc: make hfsc_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb upstream.
+
+hfsc_qlen_notify() is not idempotent either and not friendly
+to its callers, like fq_codel_dequeue(). Let's make it idempotent
+to ease qdisc_tree_reduce_backlog() callers' life:
+
+1. update_vf() decreases cl->cl_nactive, so we can check whether it is
+non-zero before calling it.
+
+2. eltree_remove() always removes RB node cl->el_node, but we can use
+ RB_EMPTY_NODE() + RB_CLEAR_NODE() to make it safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-4-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_hfsc.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -203,7 +203,10 @@ eltree_insert(struct hfsc_class *cl)
+ static inline void
+ eltree_remove(struct hfsc_class *cl)
+ {
+- rb_erase(&cl->el_node, &cl->sched->eligible);
++ if (!RB_EMPTY_NODE(&cl->el_node)) {
++ rb_erase(&cl->el_node, &cl->sched->eligible);
++ RB_CLEAR_NODE(&cl->el_node);
++ }
+ }
+
+ static inline void
+@@ -1224,7 +1227,8 @@ hfsc_qlen_notify(struct Qdisc *sch, unsi
+ /* vttree is now handled in update_vf() so that update_vf(cl, 0, 0)
+ * needs to be called explicitly to remove a class from vttree.
+ */
+- update_vf(cl, 0, 0);
++ if (cl->cl_nactive)
++ update_vf(cl, 0, 0);
+ if (cl->cl_flags & HFSC_RSC)
+ eltree_remove(cl);
+ }
--- /dev/null
+From 5ba8b837b522d7051ef81bacf3d95383ff8edce5 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:23 -0700
+Subject: sch_htb: make htb_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 5ba8b837b522d7051ef81bacf3d95383ff8edce5 upstream.
+
+htb_qlen_notify() always deactivates the HTB class and in fact could
+trigger a warning if it is already deactivated. Therefore, it is not
+idempotent and not friendly to its callers, like fq_codel_dequeue().
+
+Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers'
+life.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-2-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_htb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1485,6 +1485,8 @@ static void htb_qlen_notify(struct Qdisc
+ {
+ struct htb_class *cl = (struct htb_class *)arg;
+
++ if (!cl->prio_activity)
++ return;
+ htb_deactivate(qdisc_priv(sch), cl);
+ }
+
--- /dev/null
+From 55f9eca4bfe30a15d8656f915922e8c98b7f0728 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:26 -0700
+Subject: sch_qfq: make qfq_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 55f9eca4bfe30a15d8656f915922e8c98b7f0728 upstream.
+
+qfq_qlen_notify() always deletes its class from its active list
+with list_del_init() _and_ calls qfq_deactivate_agg() when the whole list
+becomes empty.
+
+To make it idempotent, just skip everything when it is not in the active
+list.
+
+Also change other list_del()'s to list_del_init() just to be extra safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-5-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_qfq.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -352,7 +352,7 @@ static void qfq_deactivate_class(struct
+ struct qfq_aggregate *agg = cl->agg;
+
+
+- list_del(&cl->alist); /* remove from RR queue of the aggregate */
++ list_del_init(&cl->alist); /* remove from RR queue of the aggregate */
+ if (list_empty(&agg->active)) /* agg is now inactive */
+ qfq_deactivate_agg(q, agg);
+ }
+@@ -482,6 +482,7 @@ static int qfq_change_class(struct Qdisc
+ gnet_stats_basic_sync_init(&cl->bstats);
+ cl->common.classid = classid;
+ cl->deficit = lmax;
++ INIT_LIST_HEAD(&cl->alist);
+
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+ classid, NULL);
+@@ -990,7 +991,7 @@ static struct sk_buff *agg_dequeue(struc
+ cl->deficit -= (int) len;
+
+ if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
+- list_del(&cl->alist);
++ list_del_init(&cl->alist);
+ else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
+ cl->deficit += agg->lmax;
+ list_move_tail(&cl->alist, &agg->active);
+@@ -1421,6 +1422,8 @@ static void qfq_qlen_notify(struct Qdisc
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
++ if (list_empty(&cl->alist))
++ return;
+ qfq_deactivate_class(q, cl);
+ }
+
asoc-use-of_property_read_bool.patch
asoc-soc-core-stop-using-of_property_read_bool-for-non-boolean-properties.patch
riscv-pass-patch_text-the-length-in-bytes.patch
+sch_htb-make-htb_qlen_notify-idempotent.patch
+sch_drr-make-drr_qlen_notify-idempotent.patch
+sch_hfsc-make-hfsc_qlen_notify-idempotent.patch
+sch_qfq-make-qfq_qlen_notify-idempotent.patch
+sch_ets-make-est_qlen_notify-idempotent.patch