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