Skip to content

Commit 32df05a

Browse files
rogerqmehmetb0
authored andcommitted
net: ethernet: ti: am65-cpsw: fix memleak in certain XDP cases
BugLink: https://bugs.launchpad.net/bugs/2104873 [ Upstream commit 5db8432 ] If the XDP program doesn't result in XDP_PASS then we leak the memory allocated by am65_cpsw_build_skb(). It is pointless to allocate SKB memory before running the XDP program as we would be wasting CPU cycles for cases other than XDP_PASS. Move the SKB allocation after evaluating the XDP program result. This fixes the memleak. A performance boost is seen for XDP_DROP test. XDP_DROP test: Before: 460256 rx/s 0 err/s After: 784130 rx/s 0 err/s Fixes: 8acacc4 ("net: ethernet: ti: am65-cpsw: Add minimal XDP support") Signed-off-by: Roger Quadros <rogerq@kernel.org> Link: https://patch.msgid.link/20250210-am65-cpsw-xdp-fixes-v1-1-ec6b1f7f1aca@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> [nwager: context change in hunk 3 due to missing commit: de79416 ("net: ethernet: ti: am65-cpsw: Fix multi queue Rx on J7")] Signed-off-by: Noah Wager <noah.wager@canonical.com>
1 parent 8945029 commit 32df05a

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

drivers/net/ethernet/ti/am65-cpsw-nuss.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ static void am65_cpsw_nuss_tx_cleanup(void *data, dma_addr_t desc_dma)
581581

582582
static struct sk_buff *am65_cpsw_build_skb(void *page_addr,
583583
struct net_device *ndev,
584-
unsigned int len)
584+
unsigned int len,
585+
unsigned int headroom)
585586
{
586587
struct sk_buff *skb;
587588

@@ -591,7 +592,7 @@ static struct sk_buff *am65_cpsw_build_skb(void *page_addr,
591592
if (unlikely(!skb))
592593
return NULL;
593594

594-
skb_reserve(skb, AM65_CPSW_HEADROOM);
595+
skb_reserve(skb, headroom);
595596
skb->dev = ndev;
596597

597598
return skb;
@@ -1160,19 +1161,11 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
11601161
dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info);
11611162

11621163
dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
1163-
11641164
k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
11651165

11661166
desc_idx = am65_cpsw_nuss_desc_idx(rx_chn->desc_pool, desc_rx,
11671167
rx_chn->dsize_log2);
11681168

1169-
skb = am65_cpsw_build_skb(page_addr, ndev,
1170-
AM65_CPSW_MAX_PACKET_SIZE);
1171-
if (unlikely(!skb)) {
1172-
new_page = page;
1173-
goto requeue;
1174-
}
1175-
11761169
if (port->xdp_prog) {
11771170
xdp_init_buff(&xdp, PAGE_SIZE, &port->xdp_rxq);
11781171
xdp_prepare_buff(&xdp, page_addr, AM65_CPSW_HEADROOM,
@@ -1182,9 +1175,16 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
11821175
if (*xdp_state != AM65_CPSW_XDP_PASS)
11831176
goto allocate;
11841177

1185-
/* Compute additional headroom to be reserved */
1186-
headroom = (xdp.data - xdp.data_hard_start) - skb_headroom(skb);
1187-
skb_reserve(skb, headroom);
1178+
headroom = xdp.data - xdp.data_hard_start;
1179+
} else {
1180+
headroom = AM65_CPSW_HEADROOM;
1181+
}
1182+
1183+
skb = am65_cpsw_build_skb(page_addr, ndev,
1184+
AM65_CPSW_MAX_PACKET_SIZE, headroom);
1185+
if (unlikely(!skb)) {
1186+
new_page = page;
1187+
goto requeue;
11881188
}
11891189

11901190
ndev_priv = netdev_priv(ndev);

0 commit comments

Comments
 (0)