]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: netkit: declare NETMEM_TX_NO_DMA mode
authorBobby Eshleman <bobbyeshleman@meta.com>
Thu, 14 May 2026 17:22:29 +0000 (10:22 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 19 May 2026 01:49:06 +0000 (18:49 -0700)
Some virtual devices like netkit (or ifb) never DMA and never touch frag
contents, they 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. The existing two-state
NETMEM_TX_NONE / NETMEM_TX_DMA doesn't give the TX validator enough
information to differentiate devices that will attempt DMA on the
unreadable skb from those that will simply route it untouched.

Add a third mode to the enum so drivers can indicate 1) if they have
netmem TX support, and 2) if they do, whether they are DMA-capable:

NETMEM_TX_NO_DMA - pass-through, device never DMAs

Widen dev->netmem_tx from a 1-bit field to 2 bits to fit the new value,
and declare netkit as NETMEM_TX_NO_DMA. Devmem TX support over these
devices comes in a follow-up patch.

Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
Link: https://patch.msgid.link/20260514-tcp-dm-netkit-v5-2-408c59b91e66@meta.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/net_cachelines/net_device.rst
Documentation/networking/netmem.rst
Documentation/translations/zh_CN/networking/netmem.rst
drivers/net/netkit.c
include/linux/netdevice.h

index 1c19bb7705dfacf8b2e570a6547f4a015c89eb52..7b3392553fd60c09ee1c8032b65adf7812b5a99e 100644 (file)
@@ -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
index 5ccadba4f373ee1d733795b577fe38afba3cb87e..217869d1108dd902508346952cac8fb3c8807bc6 100644 (file)
@@ -99,3 +99,6 @@ Driver TX Requirements
    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.
index 9c84423b752809e4e7eb6b4b906b1dca7eea89cf..320f3eacf51bee9fa3ac7981d14f99ba1d0d4115 100644 (file)
@@ -92,3 +92,6 @@ dma-mapping API 去处理。
 2. 驱动程序应将 `netdev->netmem_tx` 设置为适当的模式:
 
    - `NETMEM_TX_DMA`:适用于执行 DMA 的物理设备。
+
+   - `NETMEM_TX_NO_DMA`:适用于不执行 DMA 的虚拟或透传设备,但仍支持
+     处理 netmem 支持的 skb。
index 5e2eecc3165dc18a0ccd659de9ef5f65a111f445..0ad6a806d7d56747fc1879e0a0153e94d6674544 100644 (file)
@@ -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;
index b7a4503f7cdb65ff831c0cea1ae0a07bee2c16e7..bf3dd9b2c1a7edd586186de4e837ec61112bbafd 100644 (file)
@@ -1797,6 +1797,7 @@ enum netdev_stat_type {
 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 {
@@ -2143,7 +2144,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;