[PATCH] net/sched: fq_pie: enforce memory_limit without wrapped accounting

From: Samuel Moelius

Date: Mon Jun 08 2026 - 20:47:00 EST


fq_pie checks memory usage by adding the next packet size to the current
usage before comparing against memory_limit. That addition can wrap and
make an over-limit enqueue look acceptable.

The scheduler can also fail to enforce memory_limit consistently across
enqueue paths.

Use overflow-safe accounting and reject packets that would exceed
memory_limit.

Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <sam.moelius@xxxxxxxxxxxxxxx>
---
net/sched/sch_fq_pie.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
index 7becbf5362b3..752c1c32913a 100644
--- a/net/sched/sch_fq_pie.c
+++ b/net/sched/sch_fq_pie.c
@@ -152,7 +152,8 @@ static int fq_pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
sel_flow = &q->flows[idx];
/* Checks whether adding a new packet would exceed memory limit */
get_pie_cb(skb)->mem_usage = skb->truesize;
- memory_limited = q->memory_usage > q->memory_limit + skb->truesize;
+ memory_limited = (u64)q->memory_usage + skb->truesize >
+ q->memory_limit;

/* Checks if the qdisc is full */
if (unlikely(qdisc_qlen(sch) >= sch->limit)) {
@@ -160,6 +161,7 @@ static int fq_pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
goto out;
} else if (unlikely(memory_limited)) {
q->overmemory++;
+ goto out;
}

reason = QDISC_DROP_CONGESTED;
--
2.43.0