net: enable driver support for netmem TX

Drivers need to make sure not to pass netmem dma-addrs to the
dma-mapping API in order to support netmem TX.

Add helpers and netmem_dma_*() helpers that enables special handling of
netmem dma-addrs that drivers can use.

Document in netmem.rst what drivers need to do to support netmem TX.

Signed-off-by: Mina Almasry <almasrymina@google.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250508004830.4100853-7-almasrymina@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Mina Almasry 2025-05-08 00:48:26 +00:00 committed by Paolo Abeni
parent 17af8cc06a
commit 383faec0fd
5 changed files with 49 additions and 2 deletions

View File

@ -10,6 +10,7 @@ Type Name fastpath_tx_acce
=================================== =========================== =================== =================== =================================================================================== =================================== =========================== =================== =================== ===================================================================================
unsigned_long:32 priv_flags read_mostly __dev_queue_xmit(tx) 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 lltx read_mostly HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx)
unsigned long:1 netmem_tx:1; read_mostly
char name[16] char name[16]
struct netdev_name_node* name_node struct netdev_name_node* name_node
struct dev_ifalias* ifalias struct dev_ifalias* ifalias

View File

@ -188,3 +188,8 @@ Redundancy) frames from one port to another in hardware.
This should be set for devices which duplicate outgoing HSR (High-availability This should be set for devices which duplicate outgoing HSR (High-availability
Seamless Redundancy) or PRP (Parallel Redundancy Protocol) tags automatically Seamless Redundancy) or PRP (Parallel Redundancy Protocol) tags automatically
frames in hardware. frames in hardware.
* netmem-tx
This should be set for devices which support netmem TX. See
Documentation/networking/netmem.rst

View File

@ -19,8 +19,8 @@ Benefits of Netmem :
* Simplified Development: Drivers interact with a consistent API, * Simplified Development: Drivers interact with a consistent API,
regardless of the underlying memory implementation. regardless of the underlying memory implementation.
Driver Requirements Driver RX Requirements
=================== ======================
1. The driver must support page_pool. 1. The driver must support page_pool.
@ -77,3 +77,22 @@ Driver Requirements
that purpose, but be mindful that some netmem types might have longer that purpose, but be mindful that some netmem types might have longer
circulation times, such as when userspace holds a reference in zerocopy circulation times, such as when userspace holds a reference in zerocopy
scenarios. scenarios.
Driver TX Requirements
======================
1. The Driver must not pass the netmem dma_addr to any of the dma-mapping APIs
directly. This is because netmem dma_addrs may come from a source like
dma-buf that is not compatible with the dma-mapping APIs.
Helpers like netmem_dma_unmap_page_attrs() & netmem_dma_unmap_addr_set()
should be used in lieu of dma_unmap_page[_attrs](), dma_unmap_addr_set().
The netmem variants will handle netmem dma_addrs correctly regardless of the
source, delegating to the dma-mapping APIs when appropriate.
Not all dma-mapping APIs have netmem equivalents at the moment. If your
driver relies on a missing netmem API, feel free to add and propose to
netdev@, or reach out to the maintainers and/or almasrymina@google.com for
help adding the netmem API.
2. Driver should declare support by setting `netdev->netmem_tx = true`

View File

@ -1772,6 +1772,7 @@ enum netdev_reg_state {
* @lltx: device supports lockless Tx. Deprecated for real HW * @lltx: device supports lockless Tx. Deprecated for real HW
* drivers. Mainly used by logical interfaces, such as * drivers. Mainly used by logical interfaces, such as
* bonding and tunnels * bonding and tunnels
* @netmem_tx: device support netmem_tx.
* *
* @name: This is the first field of the "visible" part of this structure * @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 * (i.e. as seen by users in the "Space.c" file). It is the name
@ -2087,6 +2088,7 @@ struct net_device {
struct_group(priv_flags_fast, struct_group(priv_flags_fast,
unsigned long priv_flags:32; unsigned long priv_flags:32;
unsigned long lltx:1; unsigned long lltx:1;
unsigned long netmem_tx:1;
); );
const struct net_device_ops *netdev_ops; const struct net_device_ops *netdev_ops;
const struct header_ops *header_ops; const struct header_ops *header_ops;

View File

@ -8,6 +8,7 @@
#ifndef _NET_NETMEM_H #ifndef _NET_NETMEM_H
#define _NET_NETMEM_H #define _NET_NETMEM_H
#include <linux/dma-mapping.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <net/net_debug.h> #include <net/net_debug.h>
@ -276,4 +277,23 @@ static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
void get_netmem(netmem_ref netmem); void get_netmem(netmem_ref netmem);
void put_netmem(netmem_ref netmem); void put_netmem(netmem_ref netmem);
#define netmem_dma_unmap_addr_set(NETMEM, PTR, ADDR_NAME, VAL) \
do { \
if (!netmem_is_net_iov(NETMEM)) \
dma_unmap_addr_set(PTR, ADDR_NAME, VAL); \
else \
dma_unmap_addr_set(PTR, ADDR_NAME, 0); \
} while (0)
static inline void netmem_dma_unmap_page_attrs(struct device *dev,
dma_addr_t addr, size_t size,
enum dma_data_direction dir,
unsigned long attrs)
{
if (!addr)
return;
dma_unmap_page_attrs(dev, addr, size, dir, attrs);
}
#endif /* _NET_NETMEM_H */ #endif /* _NET_NETMEM_H */