Netmem Support for Network Drivers¶
This document outlines the requirements for network drivers to support netmem,an abstract memory type that enables features like device memory TCP. Bysupporting netmem, drivers can work with various underlying memory typeswith little to no modification.
Benefits of Netmem :
Flexibility: Netmem can be backed by different memory types (e.g.,
structpage, DMA-buf), allowing drivers to support various use cases such as devicememory TCP.Future-proof: Drivers with netmem support are ready for upcomingfeatures that rely on it.
Simplified Development: Drivers interact with a consistent API,regardless of the underlying memory implementation.
Driver RX Requirements¶
The driver must support page_pool.
The driver must support the tcp-data-split ethtool option.
The driver must use the page_pool netmem APIs for payload memory. The netmemAPIs currently 1-to-1 correspond with page APIs. Conversion to netmem shouldbe achievable by switching the page APIs to netmem APIs and tracking memoryvia netmem_refs in the driver rather than
structpage* :page_pool_alloc -> page_pool_alloc_netmem
page_pool_get_dma_addr -> page_pool_get_dma_addr_netmem
page_pool_put_page -> page_pool_put_netmem
Not all page APIs have netmem equivalents at the moment. If your driverrelies on a missing netmem API, feel free to add and propose to netdev@, orreach out to the maintainers and/oralmasrymina@google.com for help addingthe netmem API.
The driver must use the following PP_FLAGS:
PP_FLAG_DMA_MAP: netmem is not dma-mappable by the driver. The drivermust delegate the dma mapping to the page_pool, which knows whendma-mapping is (or is not) appropriate.
PP_FLAG_DMA_SYNC_DEV: netmem dma addr is not necessarily dma-syncableby the driver. The driver must delegate the dma syncing to the page_pool,which knows when dma-syncing is (or is not) appropriate.
PP_FLAG_ALLOW_UNREADABLE_NETMEM. The driver must specify this flag ifftcp-data-split is enabled.
The driver must not assume the netmem is readable and/or backed by pages.The netmem returned by the page_pool may be unreadable, in which case
netmem_address()will return NULL. The driver must correctly handleunreadable netmem, i.e. don’t attempt to handle its contents whennetmem_address()is NULL.Ideally, drivers should not have to check the underlying netmem type viahelpers like
netmem_is_net_iov()or convert the netmem to any of itsunderlying types vianetmem_to_page()ornetmem_to_net_iov(). In most cases,netmem or page_pool helpers that abstract this complexity are provided(and more can be added).The driver must use
page_pool_dma_sync_netmem_for_cpu()in lieu ofdma_sync_single_range_for_cpu(). For some memory providers, dma_syncing forCPU will be done by the page_pool, for others (particularly dmabuf memoryprovider), dma syncing for CPU is the responsibility of the userspace usingdmabuf APIs. The driver must delegate the entire dma-syncing operation tothe page_pool which will do it correctly.Avoid implementing driver-specific recycling on top of the page_pool. Driverscannot hold onto a
structpageto do their own recycling as the netmem maynot be backed by astructpage. However, you may hold onto a page_poolreference withpage_pool_fragment_netmem()orpage_pool_ref_netmem()forthat purpose, but be mindful that some netmem types might have longercirculation times, such as when userspace holds a reference in zerocopyscenarios.
Driver TX Requirements¶
The Driver must not pass the netmem dma_addr to any of the dma-mapping APIsdirectly. This is because netmem dma_addrs may come from a source likedma-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 thesource, delegating to the dma-mapping APIs when appropriate.Not all dma-mapping APIs have netmem equivalents at the moment. If yourdriver relies on a missing netmem API, feel free to add and propose tonetdev@, or reach out to the maintainers and/oralmasrymina@google.com forhelp adding the netmem API.
Driver should declare support by settingnetdev->netmem_tx = true