Skip to content

Commit 0469b41

Browse files
committed
Merge branch 'net-ethernet-ti-am65-cpsw-xdp-fixes'
Roger Quadros says: ==================== net: ethernet: ti: am65-cpsw: XDP fixes This series fixes memleak and statistics for XDP cases. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents b698b9a + 4542536 commit 0469b41

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

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

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -828,21 +828,30 @@ static void am65_cpsw_nuss_xmit_free(struct am65_cpsw_tx_chn *tx_chn,
828828
static void am65_cpsw_nuss_tx_cleanup(void *data, dma_addr_t desc_dma)
829829
{
830830
struct am65_cpsw_tx_chn *tx_chn = data;
831+
enum am65_cpsw_tx_buf_type buf_type;
831832
struct cppi5_host_desc_t *desc_tx;
833+
struct xdp_frame *xdpf;
832834
struct sk_buff *skb;
833835
void **swdata;
834836

835837
desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma);
836838
swdata = cppi5_hdesc_get_swdata(desc_tx);
837-
skb = *(swdata);
838-
am65_cpsw_nuss_xmit_free(tx_chn, desc_tx);
839+
buf_type = am65_cpsw_nuss_buf_type(tx_chn, desc_dma);
840+
if (buf_type == AM65_CPSW_TX_BUF_TYPE_SKB) {
841+
skb = *(swdata);
842+
dev_kfree_skb_any(skb);
843+
} else {
844+
xdpf = *(swdata);
845+
xdp_return_frame(xdpf);
846+
}
839847

840-
dev_kfree_skb_any(skb);
848+
am65_cpsw_nuss_xmit_free(tx_chn, desc_tx);
841849
}
842850

843851
static struct sk_buff *am65_cpsw_build_skb(void *page_addr,
844852
struct net_device *ndev,
845-
unsigned int len)
853+
unsigned int len,
854+
unsigned int headroom)
846855
{
847856
struct sk_buff *skb;
848857

@@ -852,7 +861,7 @@ static struct sk_buff *am65_cpsw_build_skb(void *page_addr,
852861
if (unlikely(!skb))
853862
return NULL;
854863

855-
skb_reserve(skb, AM65_CPSW_HEADROOM);
864+
skb_reserve(skb, headroom);
856865
skb->dev = ndev;
857866

858867
return skb;
@@ -1169,9 +1178,11 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow,
11691178
struct xdp_frame *xdpf;
11701179
struct bpf_prog *prog;
11711180
struct page *page;
1181+
int pkt_len;
11721182
u32 act;
11731183
int err;
11741184

1185+
pkt_len = *len;
11751186
prog = READ_ONCE(port->xdp_prog);
11761187
if (!prog)
11771188
return AM65_CPSW_XDP_PASS;
@@ -1189,8 +1200,10 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow,
11891200
netif_txq = netdev_get_tx_queue(ndev, tx_chn->id);
11901201

11911202
xdpf = xdp_convert_buff_to_frame(xdp);
1192-
if (unlikely(!xdpf))
1203+
if (unlikely(!xdpf)) {
1204+
ndev->stats.tx_dropped++;
11931205
goto drop;
1206+
}
11941207

11951208
__netif_tx_lock(netif_txq, cpu);
11961209
err = am65_cpsw_xdp_tx_frame(ndev, tx_chn, xdpf,
@@ -1199,14 +1212,14 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow,
11991212
if (err)
12001213
goto drop;
12011214

1202-
dev_sw_netstats_tx_add(ndev, 1, *len);
1215+
dev_sw_netstats_rx_add(ndev, pkt_len);
12031216
ret = AM65_CPSW_XDP_CONSUMED;
12041217
goto out;
12051218
case XDP_REDIRECT:
12061219
if (unlikely(xdp_do_redirect(ndev, xdp, prog)))
12071220
goto drop;
12081221

1209-
dev_sw_netstats_rx_add(ndev, *len);
1222+
dev_sw_netstats_rx_add(ndev, pkt_len);
12101223
ret = AM65_CPSW_XDP_REDIRECT;
12111224
goto out;
12121225
default:
@@ -1315,16 +1328,8 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow,
13151328
dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info);
13161329

13171330
dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
1318-
13191331
k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
13201332

1321-
skb = am65_cpsw_build_skb(page_addr, ndev,
1322-
AM65_CPSW_MAX_PACKET_SIZE);
1323-
if (unlikely(!skb)) {
1324-
new_page = page;
1325-
goto requeue;
1326-
}
1327-
13281333
if (port->xdp_prog) {
13291334
xdp_init_buff(&xdp, PAGE_SIZE, &port->xdp_rxq[flow->id]);
13301335
xdp_prepare_buff(&xdp, page_addr, AM65_CPSW_HEADROOM,
@@ -1334,9 +1339,16 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow,
13341339
if (*xdp_state != AM65_CPSW_XDP_PASS)
13351340
goto allocate;
13361341

1337-
/* Compute additional headroom to be reserved */
1338-
headroom = (xdp.data - xdp.data_hard_start) - skb_headroom(skb);
1339-
skb_reserve(skb, headroom);
1342+
headroom = xdp.data - xdp.data_hard_start;
1343+
} else {
1344+
headroom = AM65_CPSW_HEADROOM;
1345+
}
1346+
1347+
skb = am65_cpsw_build_skb(page_addr, ndev,
1348+
AM65_CPSW_MAX_PACKET_SIZE, headroom);
1349+
if (unlikely(!skb)) {
1350+
new_page = page;
1351+
goto requeue;
13401352
}
13411353

13421354
ndev_priv = netdev_priv(ndev);

0 commit comments

Comments
 (0)