Prepare 'struct i40e_xdp_buff' that contains an xdp_buff and a pointer to i40e_rx_desc in order to pass the RX descriptor to the XDP kfuncs. Also in ZC path, use XSK_CHECK_PRIV_TYPE() to ensure i40e_xdp_buff doesn't exceed the offset of cb in xdp_buff_xsk. No functional changes. Signed-off-by: Kohei Enju --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 5 ++++- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 7 ++++++- drivers/net/ethernet/intel/i40e/i40e_xsk.c | 12 ++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 31a42ee18aa0..7966d9cb8009 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3619,7 +3619,7 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) } skip: - xdp_init_buff(&ring->xdp, xdp_frame_sz, &ring->xdp_rxq); + xdp_init_buff(&ring->xdp_ctx.xdp, xdp_frame_sz, &ring->xdp_rxq); rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 4ffdb007c41a..cfaf724ee7ff 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2438,10 +2438,11 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget, unsigned int *rx_cleaned) { unsigned int total_rx_bytes = 0, total_rx_packets = 0; + struct i40e_xdp_buff *xdp_ctx = &rx_ring->xdp_ctx; u16 cleaned_count = I40E_DESC_UNUSED(rx_ring); u16 clean_threshold = rx_ring->count / 2; unsigned int offset = rx_ring->rx_offset; - struct xdp_buff *xdp = &rx_ring->xdp; + struct xdp_buff *xdp = &xdp_ctx->xdp; unsigned int xdp_xmit = 0; struct bpf_prog *xdp_prog; bool failure = false; @@ -2530,6 +2531,8 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget, if (neop) continue; + xdp_ctx->desc = rx_desc; + xdp_res = i40e_run_xdp(rx_ring, xdp, xdp_prog); if (xdp_res) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index e630493e9139..6c6ba42ee00c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -283,6 +283,11 @@ struct i40e_rx_buffer { __u32 page_count; }; +struct i40e_xdp_buff { + struct xdp_buff xdp; + const union i40e_rx_desc *desc; +}; + struct i40e_queue_stats { u64 packets; u64 bytes; @@ -345,7 +350,7 @@ struct i40e_ring { * and to resume packet building for this ring in the next call to * i40e_clean_rx_ring_irq(). */ - struct xdp_buff xdp; + struct i40e_xdp_buff xdp_ctx; /* Next descriptor to be processed; next_to_clean is updated only on * processing EOP descriptor diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c index 9f47388eaba5..51a05ce4c7ce 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c +++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c @@ -246,6 +246,8 @@ bool i40e_alloc_rx_buffers_zc(struct i40e_ring *rx_ring, u16 count) u32 nb_buffs, i; dma_addr_t dma; + XSK_CHECK_PRIV_TYPE(struct i40e_xdp_buff); + rx_desc = I40E_RX_DESC(rx_ring, ntu); xdp = i40e_rx_bi(rx_ring, ntu); @@ -396,6 +398,14 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring *rx_ring, WARN_ON_ONCE(1); } +static struct i40e_xdp_buff *xsk_buff_to_i40e_ctx(struct xdp_buff *xdp) +{ + /* xdp_buff pointer used by ZC code path is allocated as xdp_buff_xsk. + * i40e_xdp_buff private fields overlap with xdp_buff_xsk->cb. + */ + return (struct i40e_xdp_buff *)xdp; +} + /** * i40e_clean_rx_irq_zc - Consumes Rx packets from the hardware ring * @rx_ring: Rx ring @@ -472,6 +482,8 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) if (i40e_is_non_eop(rx_ring, rx_desc)) continue; + xsk_buff_to_i40e_ctx(first)->desc = rx_desc; + xdp_res = i40e_run_xdp_zc(rx_ring, first, xdp_prog); i40e_handle_xdp_result_zc(rx_ring, first, rx_desc, &rx_packets, &rx_bytes, xdp_res, &failure); -- 2.51.0