Skip to content

ixgbe: convert Rx to libeth and page_pool#6

Open
Magda-Pytel wants to merge 10 commits into
ixgbevf-xdp-publicfrom
ixgbe-XDP-public
Open

ixgbe: convert Rx to libeth and page_pool#6
Magda-Pytel wants to merge 10 commits into
ixgbevf-xdp-publicfrom
ixgbe-XDP-public

Conversation

@Magda-Pytel

Copy link
Copy Markdown
Collaborator

Convert the ixgbe Rx path from the legacy page-sharing buffer
management to libeth and page_pool, following the same approach
used in the ixgbevf conversion.

Patch 1 removes the legacy-rx ethtool private flag and makes
build_skb the only Rx code path, simplifying the driver for the
conversion.

Patch 2 converts ixgbe Rx path from page-sharing/recycling
to a simple one-page-per-packet model. Remove logic that refers
to page-sharing buffer management. This is a preparatory step
before converting the Rx path to page_pool and libeth.

Patch 3 Convert ixgbe Rx path from manual page-per-packet DMA
management to libeth/page_pool infrastructure, and integrates
libeth XDP helpers. Each packet gets its own buffer instead of
sharing pages between packets.

Patch 4 adds branch prediction hints and minor cleanups to the
Rx path, improving performance after the libeth conversion.

Patch 5 adds XDP multi-buffer support on the Rx path, allowing
XDP programs with frags support to handle packets that span
multiple buffers.

Patch 6 adds XDP_TX support in multi-buffer mode through libeth,
enabling XDP programs to transmit multi-buffer packets back out
the same interface.

Patch 7 adds XDP_REDIRECT and .ndo_xdp_xmit support through
libeth, enabling redirection of packets between interfaces via
XDP.

Patch 8 introduces pseudo header split support, copying packet
headers into a separate buffer

Patch 9 adds error handling for page pool creation in
ixgbe_configure_rx_ring() and allows buffer reallocation when
the page pool is not present.

Patch 10 eases the MTU restriction when an XDP program is
attached. With libeth page pool and multi-buffer XDP support,
MTU changes are allowed as long as the XDP program supports
frags or the frame fits in a single buffer.

Patch 1 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m5a77d9a3d6495b21d80e1f90d49470914ed950dc
Patch 2 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m4956a9538e51e0e0486b5d577fa3a1899897ba28
Patch 3 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m67766454f9439e608779ad85291e43e9de4b568d
Patch 4 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#mb10a5ccd87dc79065e6f8bcc723101b9b4966d27
Patch 5 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m74bb0fc2103acefa7a222b94bcd00cc4dae61eb1
Patch 6 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#mcc688bbe93c754d0a5e36e18e706505037f7ac51
Patch 7 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m7f0a243d405642def7f22e97a9490a2a85851886
Patch 8 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m81aae544a7e63736f2d8897d3cbaf78005bc8bd3
Patch 9 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m172f6be60eec974111c5065e8c8c2fab6f0d855b
Patch 10 based on:
commit: https://lore.kernel.org/netdev/20260304160345.1340940-1-larysa.zaremba@intel.com/T/#m5e0629f3a8d72c85b1527ef8727c9ee07a7b1428

Similarly, like for virtual function in ixgbevf, remove
ixgbe_construct_skb(), the legacy-rx private flag, and all
ring_uses_build_skb() conditionals. build_skb is now the
only RX code path.

This is a preparation for the conversion to libeth and page_pool
based Rx buffer management.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Stop sharing pages between multiple Rx buffers. Convert ixgbe Rx path
from page-sharing/recycling to a simple one-page-per-packet model.
Remove logic that refers to page-sharing buffer management. This is a
preparatory step before converting the Rx path to page_pool
and libeth.

Fixed XDP_DROP/ABORTED: reaches ixgbe_put_rx_buffer() but page
is never freed.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Convert ixgbe Rx path from manual page-per-packet DMA management
to libeth/page_pool infrastructure, and integrates libeth XDP helpers.
Each packet gets its own buffer instead of sharing pages between packets.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
* Added branch prediction hints to the ixgbe Rx path and clean up
the packet accounting.
* Moved total_rx_bytes and total_rx_packets accounting together.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Implement XDP multi-buffer support for Rx fragmented packets
using libeth_xdp.

* Added MODULE_IMPORT_NS("LIBETH_XDP")
and #include <net/libeth/types.h>
* Replaced struct sk_buff *skb in ixgbe_ring with
struct libeth_xdp_buff_stash
 and ixgbe_clean_rx_ring skb cleanup with libeth_xdp_return_stash
* Removed ixgbe_add_rx_frag()
* Reorganized ixgbe_clean_rx_irq() and ixgbe_is_non_eop()
* Updated ixgbe_xdp_setup() to allow multi-buffer XDP programs
* Added NETDEV_XDP_ACT_RX_SG in xdp_features

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Use libeth to support XDP_TX action for fragmented packets,
replacing the legacy per-frame DMA mapping path with libeth
page_pool-based bulk submission.

Replaced ixgbe_xmit_xdp_ring() with the libeth XDP TX
infrastructure. The XDP Tx ring now uses libeth_sqe instead of
ixgbe_tx_buffer for its buffer tracking.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
* Replaced the driver-specific static_branch locking mechanism
with libeth_xdpsq_lock infrastructure for XDP queue sharing.
* Updated ixgbe_xdp_xmit() to use libeth_xdp_xmit_do_bulk().
* Adjusted ixgbe_xdp_xmit_desc() to handle both XDP_TX buffers and XDP_XMIT frames.
* Updated the XSK path to use libeth_xdpsq_lock/libeth_xdpsq_unlock.

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Introduce pseudo header split support in the ixgbe driver.

* Added IXGBE_RX_SRRCTL_BUF_SIZE macro and IXGBE_FLAG2_HSPLIT flag
* Added hdr_truesize, hdr_fqes, hdr_pp, hdr_buf_len to ixgbe_ring
* Added ixgbe_rx_hsplit_wa() to copy header from data to header buffer
* Added ixgbe_rx_create_pp()/ixgbe_rx_destroy_pp() helpers
* Updated ixgbe_alloc_rx_buffers to allocate header buffers
* Updated ixgbe_clean_rx_irq to process header split
* Refactored ixgbe_setup_rx_resources to use ixgbe_rx_create_pp
* Refactored ixgbe_free_rx_resources to use ixgbe_rx_destroy_pp
* Set IXGBE_FLAG2_HSPLIT for 82599 in ixgbe_sw_init
* Updated ixgbe_xdp_setup to require mbuf frags with hsplit

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
* Moved page pool creation from ixgbe_setup_rx_resources() to
  ixgbe_configure_rx_ring()
* Moved page pool destruction to ixgbe_clean_all_rx_rings() and
  ixgbe_free_rx_resources()
* Added ixgbe_dma_dev_from_ring() helper to obtain DMA device without
  relying on page pool pointer.
* Handled XSK path in ixgbe_configure_rx_ring()

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>
Previously, MTU changes were restricted to a fixed max frame size when
XDP was active. With libeth page pool and multi-buffer XDP support, the
restriction can be loose.

* Added ixgbe_xdp_mtu_ok() to check if the given MTU is
  compatible with the attached XDP program.
* Updated ixgbe_change_mtu() to use ixgbe_xdp_mtu_ok() instead of the
  hard-coded IXGBE_RXBUFFER_3K limit.
* Updated ixgbe_xdp_setup() to use ixgbe_xdp_mtu_ok() instead of
  inline requires_mbuf logic.
* Added error handling in ixgbe_configure_rx_ring()

Signed-off-by: Magdalena Pytel <magdalena.pytel@intel.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the ixgbe driver’s Rx path away from legacy page-sharing/recycling to the libeth + page_pool infrastructure, and updates the XDP integration accordingly (including multi-buffer/XDP helpers and pseudo header split support).

Changes:

  • Switch Rx buffer management to libeth fill/completion queues backed by page_pool (and integrate libeth XDP helpers).
  • Rework XDP Tx queue handling/locking and add new ring state (__IXGBE_TX_XDP_RING_PRIMED), plus MTU/XDP frags capability gating.
  • Remove the legacy-rx private flag and update various supporting paths (self-tests, ring setup, register programming).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
drivers/net/ethernet/intel/Kconfig Selects LIBETH_XDP for ixgbe builds.
drivers/net/ethernet/intel/ixgbe/ixgbe.h Adopts libeth types, updates ring layout/state for page_pool + libeth queues.
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c Adjusts AF_XDP ZC path to new buffer structs and libeth XDP locking.
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h Renames SRRCTL buffer-size conversion macro to ..._STEP.
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c Core Rx conversion to libeth/page_pool + XDP helpers, plus ring/resource lifecycle updates.
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c Updates loopback/self-test Rx buffer access to libeth_fqe/page_pool buffers.
Comments suppressed due to low confidence (1)

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:2316

  • In the main Rx path, the skb protocol is never set (the eth_type_trans() call was removed from ixgbe_process_skb_fields(), and ixgbe_clean_rx_irq() doesn’t set it before passing the skb up). This can break upper stack parsing. Set skb->protocol via eth_type_trans() before calling ixgbe_process_skb_fields().
		/* populate checksum, timestamp, VLAN, and protocol */
		ixgbe_process_skb_fields(rx_ring, rx_desc, skb);


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1744 to +1748
rx_desc->read.pkt_addr = cpu_to_le64(addr);

/*
* Refresh the desc even if buffer_addrs didn't change
* because each write-back erases this info.
*/
rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
if (hdr_fq.pp) {
addr = libeth_rx_alloc(&hdr_fq, ntu);
if (addr == DMA_MAPPING_ERROR) {
Comment on lines +2075 to +2079
if (unlikely(!test_bit(__IXGBE_TX_XDP_RING_PRIMED,
xdp_ring->state))) {
struct ixgbe_adv_tx_context_desc *context_desc;

return rx_buffer;
}
set_bit(__IXGBE_TX_XDP_RING_PRIMED, xdp_ring->state);
Comment on lines +3687 to +3688
clear_bit(__IXGBE_HANG_CHECK_ARMED, ring->state);
clear_bit(__IXGBE_TX_XDP_RING_PRIMED, ring->state);
Comment on lines +4227 to 4233
__xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
ring->queue_index,
ixgbe_rx_napi_id(ring), 0);
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
MEM_TYPE_XSK_BUFF_POOL,
NULL));
xsk_pool_set_rxq_info(ring->xsk_pool, &ring->xdp_rxq);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants