Skip to content

Commit 49d7ee7

Browse files
committed
airoha: backport patches for memleak and multi-serdes
Backport upstream memory leak patch merged upstream and even more preliminary patch for multi-serdes rewrk. (cherry picked from commit 155c610) Link: openwrt/openwrt#23046 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
1 parent d78923d commit 49d7ee7

17 files changed

Lines changed: 828 additions & 30 deletions
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
From 4ae0604a0673e11e2075b178387151fcad5111b5 Mon Sep 17 00:00:00 2001
2+
From: Lorenzo Bianconi <lorenzo@kernel.org>
3+
Date: Tue, 7 Apr 2026 08:48:04 +0200
4+
Subject: [PATCH] net: airoha: Add dma_rmb() and READ_ONCE() in
5+
airoha_qdma_rx_process()
6+
7+
Add missing dma_rmb() in airoha_qdma_rx_process routine to make sure the
8+
DMA read operations are completed when the NIC reports the processing on
9+
the current descriptor is done. Moreover, add missing READ_ONCE() in
10+
airoha_qdma_rx_process() for DMA descriptor control fields in order to
11+
avoid any compiler reordering.
12+
13+
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
14+
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
15+
Link: https://patch.msgid.link/20260407-airoha_qdma_rx_process-fix-reordering-v3-1-91c36e9da31f@kernel.org
16+
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
17+
---
18+
drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++------
19+
1 file changed, 10 insertions(+), 6 deletions(-)
20+
21+
--- a/drivers/net/ethernet/airoha/airoha_eth.c
22+
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
23+
@@ -584,7 +584,7 @@ static int airoha_qdma_fill_rx_queue(str
24+
static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
25+
struct airoha_qdma_desc *desc)
26+
{
27+
- u32 port, sport, msg1 = le32_to_cpu(desc->msg1);
28+
+ u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
29+
30+
sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
31+
switch (sport) {
32+
@@ -612,21 +612,24 @@ static int airoha_qdma_rx_process(struct
33+
while (done < budget) {
34+
struct airoha_queue_entry *e = &q->entry[q->tail];
35+
struct airoha_qdma_desc *desc = &q->desc[q->tail];
36+
- u32 hash, reason, msg1 = le32_to_cpu(desc->msg1);
37+
- struct page *page = virt_to_head_page(e->buf);
38+
- u32 desc_ctrl = le32_to_cpu(desc->ctrl);
39+
+ u32 hash, reason, msg1, desc_ctrl;
40+
struct airoha_gdm_port *port;
41+
int data_len, len, p;
42+
+ struct page *page;
43+
44+
+ desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
45+
if (!(desc_ctrl & QDMA_DESC_DONE_MASK))
46+
break;
47+
48+
+ dma_rmb();
49+
+
50+
q->tail = (q->tail + 1) % q->ndesc;
51+
q->queued--;
52+
53+
dma_sync_single_for_cpu(eth->dev, e->dma_addr,
54+
SKB_WITH_OVERHEAD(q->buf_size), dir);
55+
56+
+ page = virt_to_head_page(e->buf);
57+
len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
58+
data_len = q->skb ? q->buf_size
59+
: SKB_WITH_OVERHEAD(q->buf_size);
60+
@@ -670,8 +673,8 @@ static int airoha_qdma_rx_process(struct
61+
* DMA descriptor. Report DSA tag to the DSA stack
62+
* via skb dst info.
63+
*/
64+
- u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG,
65+
- le32_to_cpu(desc->msg0));
66+
+ u32 msg0 = le32_to_cpu(READ_ONCE(desc->msg0));
67+
+ u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, msg0);
68+
69+
if (sptag < ARRAY_SIZE(port->dsa_meta) &&
70+
port->dsa_meta[sptag])
71+
@@ -679,6 +682,7 @@ static int airoha_qdma_rx_process(struct
72+
&port->dsa_meta[sptag]->dst);
73+
}
74+
75+
+ msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
76+
hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1);
77+
if (hash != AIROHA_RXD4_FOE_ENTRY)
78+
skb_set_hash(q->skb, jhash_1word(hash, 0),
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
From b9d8b856689d2b968495d79fe653d87fcb8ad98c Mon Sep 17 00:00:00 2001
2+
From: Lorenzo Bianconi <lorenzo@kernel.org>
3+
Date: Sun, 12 Apr 2026 10:43:26 +0200
4+
Subject: [PATCH] net: airoha: Add missing PPE configurations in
5+
airoha_ppe_hw_init()
6+
7+
Add the following PPE configuration in airoha_ppe_hw_init routine:
8+
- 6RD hw offloading is currently not supported by Netfilter flowtable.
9+
Disable explicitly PPE 6RD offloading in order to prevent PPE to learn
10+
6RD flows and eventually interrupt the traffic.
11+
- Add missing PPE bind rate configuration for L3 and L2 traffic.
12+
PPE bind rate configuration specifies the pps threshold to move a PPE
13+
entry state from UNBIND to BIND. Without this configuration this value
14+
is random.
15+
- Set ageing thresholds to the values used in the vendor SDK in order to
16+
improve connection stability under load and avoid packet loss caused by
17+
fast aging.
18+
19+
Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
20+
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
21+
Reviewed-by: Simon Horman <horms@kernel.org>
22+
Link: https://patch.msgid.link/20260412-airoha_ppe_hw_init-missing-bits-v1-1-06ac670819e3@kernel.org
23+
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
24+
---
25+
drivers/net/ethernet/airoha/airoha_ppe.c | 14 +++++++++++---
26+
1 file changed, 11 insertions(+), 3 deletions(-)
27+
28+
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
29+
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
30+
@@ -125,13 +125,13 @@ static void airoha_ppe_hw_init(struct ai
31+
airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i),
32+
PPE_BIND_AGE0_DELTA_NON_L4 |
33+
PPE_BIND_AGE0_DELTA_UDP,
34+
- FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) |
35+
- FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12));
36+
+ FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 60) |
37+
+ FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 60));
38+
airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i),
39+
PPE_BIND_AGE1_DELTA_TCP_FIN |
40+
PPE_BIND_AGE1_DELTA_TCP,
41+
FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) |
42+
- FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7));
43+
+ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 60));
44+
45+
airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i),
46+
PPE_SRAM_TABLE_EN_MASK |
47+
@@ -159,7 +159,15 @@ static void airoha_ppe_hw_init(struct ai
48+
FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
49+
dram_num_entries));
50+
51+
+ airoha_fe_rmw(eth, REG_PPE_BIND_RATE(i),
52+
+ PPE_BIND_RATE_L2B_BIND_MASK |
53+
+ PPE_BIND_RATE_BIND_MASK,
54+
+ FIELD_PREP(PPE_BIND_RATE_L2B_BIND_MASK, 0x1e) |
55+
+ FIELD_PREP(PPE_BIND_RATE_BIND_MASK, 0x1e));
56+
+
57+
airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED);
58+
+ airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
59+
+ PPE_FLOW_CFG_IP6_6RD_MASK);
60+
61+
for (p = 0; p < ARRAY_SIZE(eth->ports); p++) {
62+
struct airoha_gdm_port *port = eth->ports[p];
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
From 656121b155030086b01cfce9bd31b0c925ee6860 Mon Sep 17 00:00:00 2001
2+
From: Lorenzo Bianconi <lorenzo@kernel.org>
3+
Date: Wed, 8 Apr 2026 20:26:56 +0200
4+
Subject: [PATCH] net: airoha: Add missing RX_CPU_IDX() configuration in
5+
airoha_qdma_cleanup_rx_queue()
6+
7+
When the descriptor index written in REG_RX_CPU_IDX() is equal to the one
8+
stored in REG_RX_DMA_IDX(), the hw will stop since the QDMA RX ring is
9+
empty.
10+
Add missing REG_RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue
11+
routine during QDMA RX ring cleanup.
12+
13+
Fixes: 514aac359987 ("net: airoha: Add missing cleanup bits in airoha_qdma_cleanup_rx_queue()")
14+
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
15+
Link: https://patch.msgid.link/20260408-airoha-cpu-idx-airoha_qdma_cleanup_rx_queue-v1-1-8efa64844308@kernel.org
16+
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
17+
---
18+
drivers/net/ethernet/airoha/airoha_eth.c | 5 +++++
19+
1 file changed, 5 insertions(+)
20+
21+
--- a/drivers/net/ethernet/airoha/airoha_eth.c
22+
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
23+
@@ -824,6 +824,11 @@ static void airoha_qdma_cleanup_rx_queue
24+
}
25+
26+
q->head = q->tail;
27+
+ /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
28+
+ * empty.
29+
+ */
30+
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
31+
+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
32+
airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
33+
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
34+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
From 02f72964395911e7a09bb2ea2fe6f79eda4ea2c2 Mon Sep 17 00:00:00 2001
2+
From: Lorenzo Bianconi <lorenzo@kernel.org>
3+
Date: Wed, 8 Apr 2026 12:20:09 +0200
4+
Subject: [PATCH] net: airoha: Fix FE_PSE_BUF_SET configuration if PPE2 is
5+
available
6+
7+
airoha_fe_set routine is used to set specified bits to 1 in the selected
8+
register. In the FE_PSE_BUF_SET case this can due to a overestimation of
9+
the required buffers for I/O queues since we can miss to set some bits
10+
of PSE_ALLRSV_MASK subfield to 0. Fix the issue relying on airoha_fe_rmw
11+
routine instead.
12+
13+
Fixes: 8e38e08f2c560 ("net: airoha: fix PSE memory configuration in airoha_fe_pse_ports_init()")
14+
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
15+
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
16+
Link: https://patch.msgid.link/20260408-airoha-reg_fe_pse_buf_set-v1-1-0c4fa8f4d1d9@kernel.org
17+
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
18+
---
19+
drivers/net/ethernet/airoha/airoha_eth.c | 8 +++++---
20+
1 file changed, 5 insertions(+), 3 deletions(-)
21+
22+
--- a/drivers/net/ethernet/airoha/airoha_eth.c
23+
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
24+
@@ -293,16 +293,18 @@ static void airoha_fe_pse_ports_init(str
25+
[FE_PSE_PORT_GDM4] = 2,
26+
[FE_PSE_PORT_CDM5] = 2,
27+
};
28+
- u32 all_rsv;
29+
int q;
30+
31+
- all_rsv = airoha_fe_get_pse_all_rsv(eth);
32+
if (airoha_ppe_is_enabled(eth, 1)) {
33+
+ u32 all_rsv;
34+
+
35+
/* hw misses PPE2 oq rsv */
36+
+ all_rsv = airoha_fe_get_pse_all_rsv(eth);
37+
all_rsv += PSE_RSV_PAGES *
38+
pse_port_num_queues[FE_PSE_PORT_PPE2];
39+
+ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,
40+
+ FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));
41+
}
42+
- airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv);
43+
44+
/* CMD1 */
45+
for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
From 285fa6b1e03cff78ead0383e1b259c44b95faf90 Mon Sep 17 00:00:00 2001
2+
From: Lorenzo Bianconi <lorenzo@kernel.org>
3+
Date: Thu, 2 Apr 2026 14:57:10 +0200
4+
Subject: [PATCH] net: airoha: Fix memory leak in airoha_qdma_rx_process()
5+
6+
If an error occurs on the subsequents buffers belonging to the
7+
non-linear part of the skb (e.g. due to an error in the payload length
8+
reported by the NIC or if we consumed all the available fragments for
9+
the skb), the page_pool fragment will not be linked to the skb so it will
10+
not return to the pool in the airoha_qdma_rx_process() error path. Fix the
11+
memory leak partially reverting commit 'd6d2b0e1538d ("net: airoha: Fix
12+
page recycling in airoha_qdma_rx_process()")' and always running
13+
page_pool_put_full_page routine in the airoha_qdma_rx_process() error
14+
path.
15+
16+
Fixes: d6d2b0e1538d ("net: airoha: Fix page recycling in airoha_qdma_rx_process()")
17+
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
18+
Reviewed-by: Simon Horman <horms@kernel.org>
19+
Link: https://patch.msgid.link/20260402-airoha_qdma_rx_process-mem-leak-fix-v1-1-b5706f402d3c@kernel.org
20+
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
21+
---
22+
drivers/net/ethernet/airoha/airoha_eth.c | 3 +--
23+
1 file changed, 1 insertion(+), 2 deletions(-)
24+
25+
--- a/drivers/net/ethernet/airoha/airoha_eth.c
26+
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
27+
@@ -703,9 +703,8 @@ free_frag:
28+
if (q->skb) {
29+
dev_kfree_skb(q->skb);
30+
q->skb = NULL;
31+
- } else {
32+
- page_pool_put_full_page(q->page_pool, page, true);
33+
}
34+
+ page_pool_put_full_page(q->page_pool, page, true);
35+
}
36+
airoha_qdma_fill_rx_queue(q);
37+

0 commit comments

Comments
 (0)