Skip to content

Commit 51a8339

Browse files
Dimitris MichailidisPaolo Abeni
Dimitris Michailidis
authored and
Paolo Abeni
committed
net/funeth: Fix fun_xdp_tx() and XDP packet reclaim
The current implementation of fun_xdp_tx(), used for XPD_TX, is incorrect in that it takes an address/length pair and later releases it with page_frag_free(). It is OK for XDP_TX but the same code is used by ndo_xdp_xmit. In that case it loses the XDP memory type and releases the packet incorrectly for some of the types. Assorted breakage follows. Change fun_xdp_tx() to take xdp_frame and rely on xdp_return_frame() in reclaim. Fixes: db37bc1 ("net/funeth: add the data path") Signed-off-by: Dimitris Michailidis <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent bf84719 commit 51a8339

File tree

3 files changed

+16
-15
lines changed

3 files changed

+16
-15
lines changed

drivers/net/ethernet/fungible/funeth/funeth_rx.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static void *fun_run_xdp(struct funeth_rxq *q, skb_frag_t *frags, void *buf_va,
142142
int ref_ok, struct funeth_txq *xdp_q)
143143
{
144144
struct bpf_prog *xdp_prog;
145+
struct xdp_frame *xdpf;
145146
struct xdp_buff xdp;
146147
u32 act;
147148

@@ -163,7 +164,9 @@ static void *fun_run_xdp(struct funeth_rxq *q, skb_frag_t *frags, void *buf_va,
163164
case XDP_TX:
164165
if (unlikely(!ref_ok))
165166
goto pass;
166-
if (!fun_xdp_tx(xdp_q, xdp.data, xdp.data_end - xdp.data))
167+
168+
xdpf = xdp_convert_buff_to_frame(&xdp);
169+
if (!xdpf || !fun_xdp_tx(xdp_q, xdpf))
167170
goto xdp_error;
168171
FUN_QSTAT_INC(q, xdp_tx);
169172
q->xdp_flush |= FUN_XDP_FLUSH_TX;

drivers/net/ethernet/fungible/funeth/funeth_tx.c

+9-11
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ static unsigned int fun_xdpq_clean(struct funeth_txq *q, unsigned int budget)
466466

467467
do {
468468
fun_xdp_unmap(q, reclaim_idx);
469-
page_frag_free(q->info[reclaim_idx].vaddr);
469+
xdp_return_frame(q->info[reclaim_idx].xdpf);
470470

471471
trace_funeth_tx_free(q, reclaim_idx, 1, head);
472472

@@ -479,11 +479,11 @@ static unsigned int fun_xdpq_clean(struct funeth_txq *q, unsigned int budget)
479479
return npkts;
480480
}
481481

482-
bool fun_xdp_tx(struct funeth_txq *q, void *data, unsigned int len)
482+
bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf)
483483
{
484484
struct fun_eth_tx_req *req;
485485
struct fun_dataop_gl *gle;
486-
unsigned int idx;
486+
unsigned int idx, len;
487487
dma_addr_t dma;
488488

489489
if (fun_txq_avail(q) < FUN_XDP_CLEAN_THRES)
@@ -494,7 +494,8 @@ bool fun_xdp_tx(struct funeth_txq *q, void *data, unsigned int len)
494494
return false;
495495
}
496496

497-
dma = dma_map_single(q->dma_dev, data, len, DMA_TO_DEVICE);
497+
len = xdpf->len;
498+
dma = dma_map_single(q->dma_dev, xdpf->data, len, DMA_TO_DEVICE);
498499
if (unlikely(dma_mapping_error(q->dma_dev, dma))) {
499500
FUN_QSTAT_INC(q, tx_map_err);
500501
return false;
@@ -514,7 +515,7 @@ bool fun_xdp_tx(struct funeth_txq *q, void *data, unsigned int len)
514515
gle = (struct fun_dataop_gl *)req->dataop.imm;
515516
fun_dataop_gl_init(gle, 0, 0, len, dma);
516517

517-
q->info[idx].vaddr = data;
518+
q->info[idx].xdpf = xdpf;
518519

519520
u64_stats_update_begin(&q->syncp);
520521
q->stats.tx_bytes += len;
@@ -545,12 +546,9 @@ int fun_xdp_xmit_frames(struct net_device *dev, int n,
545546
if (unlikely(q_idx >= fp->num_xdpqs))
546547
return -ENXIO;
547548

548-
for (q = xdpqs[q_idx], i = 0; i < n; i++) {
549-
const struct xdp_frame *xdpf = frames[i];
550-
551-
if (!fun_xdp_tx(q, xdpf->data, xdpf->len))
549+
for (q = xdpqs[q_idx], i = 0; i < n; i++)
550+
if (!fun_xdp_tx(q, frames[i]))
552551
break;
553-
}
554552

555553
if (unlikely(flags & XDP_XMIT_FLUSH))
556554
fun_txq_wr_db(q);
@@ -577,7 +575,7 @@ static void fun_xdpq_purge(struct funeth_txq *q)
577575
unsigned int idx = q->cons_cnt & q->mask;
578576

579577
fun_xdp_unmap(q, idx);
580-
page_frag_free(q->info[idx].vaddr);
578+
xdp_return_frame(q->info[idx].xdpf);
581579
q->cons_cnt++;
582580
}
583581
}

drivers/net/ethernet/fungible/funeth/funeth_txrx.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ struct funeth_txq_stats { /* per Tx queue SW counters */
9595

9696
struct funeth_tx_info { /* per Tx descriptor state */
9797
union {
98-
struct sk_buff *skb; /* associated packet */
99-
void *vaddr; /* start address for XDP */
98+
struct sk_buff *skb; /* associated packet (sk_buff path) */
99+
struct xdp_frame *xdpf; /* associated XDP frame (XDP path) */
100100
};
101101
};
102102

@@ -245,7 +245,7 @@ static inline int fun_irq_node(const struct fun_irq *p)
245245
int fun_rxq_napi_poll(struct napi_struct *napi, int budget);
246246
int fun_txq_napi_poll(struct napi_struct *napi, int budget);
247247
netdev_tx_t fun_start_xmit(struct sk_buff *skb, struct net_device *netdev);
248-
bool fun_xdp_tx(struct funeth_txq *q, void *data, unsigned int len);
248+
bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf);
249249
int fun_xdp_xmit_frames(struct net_device *dev, int n,
250250
struct xdp_frame **frames, u32 flags);
251251

0 commit comments

Comments
 (0)