xref: /linux/Documentation/networking/netmem.rst (revision 70c29b35fd87f87a7b8dad6eb8d55ce54a0d549a)
1.. SPDX-License-Identifier: GPL-2.0
2
3==================================
4Netmem Support for Network Drivers
5==================================
6
7This document outlines the requirements for network drivers to support netmem,
8an abstract memory type that enables features like device memory TCP. By
9supporting netmem, drivers can work with various underlying memory types
10with little to no modification.
11
12Benefits of Netmem :
13
14* Flexibility: Netmem can be backed by different memory types (e.g., struct
15  page, DMA-buf), allowing drivers to support various use cases such as device
16  memory TCP.
17* Future-proof: Drivers with netmem support are ready for upcoming
18  features that rely on it.
19* Simplified Development: Drivers interact with a consistent API,
20  regardless of the underlying memory implementation.
21
22Design Principles
23=================
24
25Memory providers (or the default ``page_pool`` allocator) allocate underlying
26memory (``struct net_iov`` or ``struct page``), cast it to ``netmem_ref``, and
27supply it to ``page_pool``. The ``page_pool``, drivers, and networking stack
28operate on ``netmem_ref`` as the abstract type. Existing ``page_pool`` APIs
29that allocate or free ``struct page`` are legacy compatibility wrappers for
30drivers that do not yet support ``netmem_ref``. Code that is not yet
31``netmem``-aware should be converted to ``netmem_ref`` unless it will never
32need to support ``netmem``.
33
341. **Operate on netmem_ref, do not downcast**: ``page_pool``, drivers, and the
35   core networking stack should deal with ``netmem_ref`` rather than
36   ``struct net_iov`` or ``struct page``. Downcasting ``netmem_ref`` to
37   ``struct net_iov`` or ``struct page`` is not allowed unless a code path
38   strictly cannot function without knowing the underlying memory type (for
39   example, ``kmap_local_page()``). In those cases, to keep call sites simple,
40   add a ``netmem`` helper that performs the operation on behalf of the caller,
41   cleanly handles all ``net_iov`` and ``page`` cases, and returns an error if
42   the ``netmem`` type cannot support the requested operation.
43
442. **Decouple memory providers from net_iov**: Memory providers are not
45   architecturally limited to ``struct net_iov``; a memory provider that returns
46   ``struct page``-backed ``netmem_ref``\ s to upper layers is allowed. Today,
47   in-tree memory providers only supply ``struct net_iov`` and some existing
48   code still reflects that limitation, but new code must not assume that using
49   a memory provider implies ``net_iov`` memory and should, as much as possible,
50   generalize existing limitations to match the design principles.
51
523. **Decouple net_iov from unreadability**: ``struct net_iov`` is flexible and
53   has no inherent restrictions; it may represent either CPU-readable or
54   unreadable memory. Today, in-tree ``net_iov`` implementations are unreadable
55   by the CPU (``netmem_address()`` returns ``NULL``) and some existing code
56   still reflects that limitation, but new code must not assume ``net_iov``
57   implies unreadable memory (check readability via ``netmem_address()`` or
58   ``skb_frags_readable()`` instead) and should, as much as possible, generalize
59   existing limitations to match the design principles.
60
614. **Delegate complexity to the lowest layer**: Each layer must respect its
62   abstraction boundary. ``page_pool`` must not implement per-memory-provider
63   custom logic in its main code; instead, it delegates provider-specific
64   handling to ``struct memory_provider_ops``. Similarly, core networking code
65   should avoid per-``netmem``-type branching and instead delegate operations
66   to ``netmem`` helpers that handle the underlying memory type.
67
685. **Do not mix skb fragment memory sources**: All ``frags[]`` in an
69   ``sk_buff`` must either be ``struct page``-backed or belong to the same
70   memory provider instance (for example, the same ``devmem`` binding or
71   ``io_uring`` area). Mixing ``struct page`` and memory-provider fragments,
72   or mixing fragments from different memory providers within a single
73   ``sk_buff``, is not allowed (including when coalescing ``sk_buff``\ s).
74
75Driver RX Requirements
76======================
77
781. The driver must support page_pool.
79
802. The driver must support the tcp-data-split ethtool option.
81
823. The driver must use the page_pool netmem APIs for payload memory. The netmem
83   APIs currently 1-to-1 correspond with page APIs. Conversion to netmem should
84   be achievable by switching the page APIs to netmem APIs and tracking memory
85   via netmem_refs in the driver rather than struct page * :
86
87   - page_pool_alloc -> page_pool_alloc_netmem
88   - page_pool_get_dma_addr -> page_pool_get_dma_addr_netmem
89   - page_pool_put_page -> page_pool_put_netmem
90
91   Not all page APIs have netmem equivalents at the moment. If your driver
92   relies on a missing netmem API, feel free to add and propose to netdev@, or
93   reach out to the maintainers and/or almasrymina@google.com for help adding
94   the netmem API.
95
964. The driver must use the following PP_FLAGS:
97
98   - PP_FLAG_DMA_MAP: netmem is not dma-mappable by the driver. The driver
99     must delegate the dma mapping to the page_pool, which knows when
100     dma-mapping is (or is not) appropriate.
101   - PP_FLAG_DMA_SYNC_DEV: netmem dma addr is not necessarily dma-syncable
102     by the driver. The driver must delegate the dma syncing to the page_pool,
103     which knows when dma-syncing is (or is not) appropriate.
104   - PP_FLAG_ALLOW_UNREADABLE_NETMEM. The driver must specify this flag iff
105     tcp-data-split is enabled.
106
1075. The driver must not assume the netmem is readable and/or backed by pages.
108   The netmem returned by the page_pool may be unreadable, in which case
109   netmem_address() will return NULL. The driver must correctly handle
110   unreadable netmem, i.e. don't attempt to handle its contents when
111   netmem_address() is NULL.
112
113   Ideally, drivers should not have to check the underlying netmem type via
114   helpers like netmem_is_net_iov() or convert the netmem to any of its
115   underlying types via netmem_to_page() or netmem_to_net_iov(). In most cases,
116   netmem or page_pool helpers that abstract this complexity are provided
117   (and more can be added).
118
1196. The driver must use page_pool_dma_sync_netmem_for_cpu() in lieu of
120   dma_sync_single_range_for_cpu(). For some memory providers, dma_syncing for
121   CPU will be done by the page_pool, for others (particularly dmabuf memory
122   provider), dma syncing for CPU is the responsibility of the userspace using
123   dmabuf APIs. The driver must delegate the entire dma-syncing operation to
124   the page_pool which will do it correctly.
125
1267. Avoid implementing driver-specific recycling on top of the page_pool. Drivers
127   cannot hold onto a struct page to do their own recycling as the netmem may
128   not be backed by a struct page. However, you may hold onto a page_pool
129   reference with page_pool_fragment_netmem() or page_pool_ref_netmem() for
130   that purpose, but be mindful that some netmem types might have longer
131   circulation times, such as when userspace holds a reference in zerocopy
132   scenarios.
133
134Driver TX Requirements
135======================
136
1371. The Driver must not pass the netmem dma_addr to any of the dma-mapping APIs
138   directly. This is because netmem dma_addrs may come from a source like
139   dma-buf that is not compatible with the dma-mapping APIs.
140
141   Helpers like netmem_dma_unmap_page_attrs() & netmem_dma_unmap_addr_set()
142   should be used in lieu of dma_unmap_page[_attrs](), dma_unmap_addr_set().
143   The netmem variants will handle netmem dma_addrs correctly regardless of the
144   source, delegating to the dma-mapping APIs when appropriate.
145
146   Not all dma-mapping APIs have netmem equivalents at the moment. If your
147   driver relies on a missing netmem API, feel free to add and propose to
148   netdev@, or reach out to the maintainers and/or almasrymina@google.com for
149   help adding the netmem API.
150
1512. Driver should declare support by setting `netdev->netmem_tx` to the
152   appropriate mode:
153
154   - `NETMEM_TX_DMA`: for physical devices that perform DMA.
155
156   - `NETMEM_TX_NO_DMA`: for virtual or passthrough devices that do
157     not DMA, but still support handling of netmem-backed skbs.
158