blob: 05a888006e2669bface35905a28620a88ac9bb9f [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Wed, 25 Nov 2020 18:03:46 +0100
3Subject: [PATCH] net/fq_impl: bulk-free packets from a flow on overmemory
4
5This is similar to what sch_fq_codel does. It also amortizes the worst
6case cost of a follow-up patch that changes the selection of the biggest
7flow for dropping packets
8
9Signed-off-by: Felix Fietkau <nbd@nbd.name>
10---
11
12--- a/include/net/fq_impl.h
13+++ b/include/net/fq_impl.h
14@@ -11,17 +11,25 @@
15
16 /* functions that are embedded into includer */
17
18+
19+static void
20+__fq_adjust_removal(struct fq *fq, struct fq_flow *flow, unsigned int packets,
21+ unsigned int bytes, unsigned int truesize)
22+{
23+ struct fq_tin *tin = flow->tin;
24+
25+ tin->backlog_bytes -= bytes;
26+ tin->backlog_packets -= packets;
27+ flow->backlog -= bytes;
28+ fq->backlog -= packets;
29+ fq->memory_usage -= truesize;
30+}
31+
32 static void fq_adjust_removal(struct fq *fq,
33 struct fq_flow *flow,
34 struct sk_buff *skb)
35 {
36- struct fq_tin *tin = flow->tin;
37-
38- tin->backlog_bytes -= skb->len;
39- tin->backlog_packets--;
40- flow->backlog -= skb->len;
41- fq->backlog--;
42- fq->memory_usage -= skb->truesize;
43+ __fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
44 }
45
46 static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
47@@ -59,6 +67,34 @@ static struct sk_buff *fq_flow_dequeue(s
48 return skb;
49 }
50
51+static int fq_flow_drop(struct fq *fq, struct fq_flow *flow,
52+ fq_skb_free_t free_func)
53+{
54+ unsigned int packets = 0, bytes = 0, truesize = 0;
55+ struct fq_tin *tin = flow->tin;
56+ struct sk_buff *skb;
57+ int pending;
58+
59+ lockdep_assert_held(&fq->lock);
60+
61+ pending = min_t(int, 32, skb_queue_len(&flow->queue) / 2);
62+ do {
63+ skb = __skb_dequeue(&flow->queue);
64+ if (!skb)
65+ break;
66+
67+ packets++;
68+ bytes += skb->len;
69+ truesize += skb->truesize;
70+ free_func(fq, tin, flow, skb);
71+ } while (packets < pending);
72+
73+ __fq_adjust_removal(fq, flow, packets, bytes, truesize);
74+ fq_rejigger_backlog(fq, flow);
75+
76+ return packets;
77+}
78+
79 static struct sk_buff *fq_tin_dequeue(struct fq *fq,
80 struct fq_tin *tin,
81 fq_tin_dequeue_t dequeue_func)
82@@ -190,12 +226,9 @@ static void fq_tin_enqueue(struct fq *fq
83 if (!flow)
84 return;
85
86- skb = fq_flow_dequeue(fq, flow);
87- if (!skb)
88+ if (!fq_flow_drop(fq, flow, free_func))
89 return;
90
91- free_func(fq, flow->tin, flow, skb);
92-
93 flow->tin->overlimit++;
94 fq->overlimit++;
95 if (oom) {