Re: [PATCH net-next v2 1/6] net: add netmem_tx modes that indicate dma capability

From: Harshitha Ramamurthy

Date: Tue May 05 2026 - 13:44:46 EST


On Mon, May 4, 2026 at 5:27 PM Bobby Eshleman <bobbyeshleman@xxxxxxxxx> wrote:
>
> From: Bobby Eshleman <bobbyeshleman@xxxxxxxx>
>
> Devices that support netmem TX previously set dev->netmem_tx = true.
> This was checked in validate_xmit_unreadable_skb() to drop unreadable
> skbs (skbs with dmabuf-backed frags) before they reach drivers that
> would mishandle them or devices that would not have the iommu mappings
> for them.
>
> Some virtual devices like netkit (or ifb) never DMA and never touch frag
> contents, as they essentially just forward the skb to another device.
> They are unable to forward unreadable skbs, however, because they fail
> to pass TX validation checks on dev->netmem_tx. This single bit flag
> doesn't give the TX validator enough information to differentiate
> devices that will attempt DMA on the unreadable skb and those that will
> simply route it untouched.
>
> This patch fixes this issue by adding an additional bit to netmem_tx, so
> that drivers can indicate 1) if they have netmem support, and 2) if they
> do, are they DMA-capable or not?
>
> Replace the boolean with a 2-bit enum:
>
> NETMEM_TX_NONE - no netmem TX support (drop unreadable skbs)
> NETMEM_TX_DMA - full support, device does DMA
> NETMEM_TX_NO_DMA - pass-through, device never DMAs
>
> Update drivers to reflect these definitions. NIC drivers use
> NETMEM_TX_DMA, and netkit uses NETMEM_TX_NO_DMA.
>
> Signed-off-by: Bobby Eshleman <bobbyeshleman@xxxxxxxx>
> ---
> Changes in v2:
> - Squash driver conversion patches (2-5) into patch 1 (Jakub)
> ---
> Documentation/networking/net_cachelines/net_device.rst | 2 +-
> Documentation/networking/netmem.rst | 8 +++++++-
> Documentation/translations/zh_CN/networking/netmem.rst | 7 ++++++-
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
> drivers/net/ethernet/google/gve/gve_main.c | 2 +-
> drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
> drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 +-
> drivers/net/netkit.c | 1 +
> include/linux/netdevice.h | 11 +++++++++--
> 9 files changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
> index 1c19bb7705df..c85784259544 100644
> --- a/Documentation/networking/net_cachelines/net_device.rst
> +++ b/Documentation/networking/net_cachelines/net_device.rst
> @@ -10,7 +10,7 @@ Type Name fastpath_tx_acce
> =================================== =========================== =================== =================== ===================================================================================
> unsigned_long:32 priv_flags read_mostly __dev_queue_xmit(tx)
> unsigned_long:1 lltx read_mostly HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx)
> -unsigned long:1 netmem_tx:1; read_mostly
> +unsigned long:2 netmem_tx:2; read_mostly
> char name[16]
> struct netdev_name_node* name_node
> struct dev_ifalias* ifalias
> diff --git a/Documentation/networking/netmem.rst b/Documentation/networking/netmem.rst
> index b63aded46337..217869d1108d 100644
> --- a/Documentation/networking/netmem.rst
> +++ b/Documentation/networking/netmem.rst
> @@ -95,4 +95,10 @@ Driver TX Requirements
> netdev@, or reach out to the maintainers and/or almasrymina@xxxxxxxxxx for
> help adding the netmem API.
>
> -2. Driver should declare support by setting `netdev->netmem_tx = true`
> +2. Driver should declare support by setting `netdev->netmem_tx` to the
> + appropriate mode:
> +
> + - `NETMEM_TX_DMA`: for physical devices that perform DMA.
> +
> + - `NETMEM_TX_NO_DMA`: for virtual or passthrough devices that do
> + not DMA, but still support handling of netmem-backed skbs.
> diff --git a/Documentation/translations/zh_CN/networking/netmem.rst b/Documentation/translations/zh_CN/networking/netmem.rst
> index fe351a240f02..320f3eacf51b 100644
> --- a/Documentation/translations/zh_CN/networking/netmem.rst
> +++ b/Documentation/translations/zh_CN/networking/netmem.rst
> @@ -89,4 +89,9 @@ dma-mapping API 去处理。
> 使用某个还不存在的 netmem API,你可以自行添加并提交到 netdev@,也可以联系维护
> 人员或者发送邮件至 almasrymina@xxxxxxxxxx 寻求帮助。
>
> -2. 驱动程序应通过设置 netdev->netmem_tx = true 来表明自身支持 netmem 功能。
> +2. 驱动程序应将 `netdev->netmem_tx` 设置为适当的模式:
> +
> + - `NETMEM_TX_DMA`:适用于执行 DMA 的物理设备。
> +
> + - `NETMEM_TX_NO_DMA`:适用于不执行 DMA 的虚拟或透传设备,但仍支持
> + 处理 netmem 支持的 skb。
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index 8c55874f44ca..ed9c22dc4a5a 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -17120,7 +17120,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops_unsupp;
> if (BNXT_SUPPORTS_QUEUE_API(bp))
> dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops;
> - dev->netmem_tx = true;
> + dev->netmem_tx = NETMEM_TX_DMA;
>
> rc = register_netdev(dev);
> if (rc)
> diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
> index 424d973c97f2..dd2b8f087163 100644
> --- a/drivers/net/ethernet/google/gve/gve_main.c
> +++ b/drivers/net/ethernet/google/gve/gve_main.c
> @@ -2894,7 +2894,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> goto abort_with_wq;
>
> if (!gve_is_gqi(priv) && !gve_is_qpl(priv))
> - dev->netmem_tx = true;
> + dev->netmem_tx = NETMEM_TX_DMA;

Acked-by: Harshitha Ramamurthy <hramamurthy@xxxxxxxxxx>

>
> err = register_netdev(dev);
> if (err)
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index 5a46870c4b74..fc49aae38807 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> @@ -5924,7 +5924,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
>
> netdev->priv_flags |= IFF_UNICAST_FLT;
>
> - netdev->netmem_tx = true;
> + netdev->netmem_tx = NETMEM_TX_DMA;
>
> netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
> mlx5e_set_xdp_feature(priv);
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> index c406a3b56b37..138e522ef9b9 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> @@ -752,7 +752,7 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
> netdev->netdev_ops = &fbnic_netdev_ops;
> netdev->stat_ops = &fbnic_stat_ops;
> netdev->queue_mgmt_ops = &fbnic_queue_mgmt_ops;
> - netdev->netmem_tx = true;
> + netdev->netmem_tx = NETMEM_TX_DMA;
>
> fbnic_set_ethtool_ops(netdev);
>
> diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c
> index 5e2eecc3165d..0ad6a806d7d5 100644
> --- a/drivers/net/netkit.c
> +++ b/drivers/net/netkit.c
> @@ -466,6 +466,7 @@ static void netkit_setup(struct net_device *dev)
> dev->priv_flags |= IFF_NO_QUEUE;
> dev->priv_flags |= IFF_DISABLE_NETPOLL;
> dev->lltx = true;
> + dev->netmem_tx = NETMEM_TX_NO_DMA;
>
> dev->netdev_ops = &netkit_netdev_ops;
> dev->ethtool_ops = &netkit_ethtool_ops;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0e1e581efc5a..11d68e75eb4f 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1788,6 +1788,12 @@ enum netdev_stat_type {
> NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
> };
>
> +enum netmem_tx_mode {
> + NETMEM_TX_NONE, /* no netmem TX support */
> + NETMEM_TX_DMA, /* DMA-capable netmem TX (real HW) */
> + NETMEM_TX_NO_DMA, /* no DMA, e.g. passthrough for virtual devs */
> +};
> +
> enum netdev_reg_state {
> NETREG_UNINITIALIZED = 0,
> NETREG_REGISTERED, /* completed register_netdevice */
> @@ -1809,7 +1815,8 @@ enum netdev_reg_state {
> * @lltx: device supports lockless Tx. Deprecated for real HW
> * drivers. Mainly used by logical interfaces, such as
> * bonding and tunnels
> - * @netmem_tx: device support netmem_tx.
> + * @netmem_tx: device netmem TX mode (NETMEM_TX_NONE, NETMEM_TX_DMA,
> + * or NETMEM_TX_NO_DMA).
> *
> * @name: This is the first field of the "visible" part of this structure
> * (i.e. as seen by users in the "Space.c" file). It is the name
> @@ -2132,7 +2139,7 @@ struct net_device {
> struct_group(priv_flags_fast,
> unsigned long priv_flags:32;
> unsigned long lltx:1;
> - unsigned long netmem_tx:1;
> + unsigned long netmem_tx:2;
> );
> const struct net_device_ops *netdev_ops;
> const struct header_ops *header_ops;
>
> --
> 2.52.0
>