From: Dragos Tatulea <dtatulea@nvidia.com>
To: Luigi Rizzo <lrizzo@google.com>,
Luigi Rizzo <rizzo.unipi@gmail.com>,
Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
Christoph Hellwig <hch@lst.de>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Andrew Morton <akpm@linux-foundation.org>,
Vlastimil Babka <vbabka@kernel.org>,
David Hildenbrand <david@kernel.org>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>,
Jonathan Corbet <corbet@lwn.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Willem de Bruijn <willemb@google.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
Joshua Washington <joshwash@google.com>,
Harshitha Ramamurthy <hramamurthy@google.com>,
Saeed Mahameed <saeedm@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>,
Tony Nguyen <anthony.l.nguyen@intel.com>,
Przemek Kitszel <przemyslaw.kitszel@intel.com>,
Alexander Lobakin <aleksander.lobakin@intel.com>,
Michael Chan <michael.chan@broadcom.com>,
Pavan Chebbi <pavan.chebbi@broadcom.com>,
iommu@lists.linux.dev, netdev@vger.kernel.org,
linux-mm@kvack.org, driver-core@lists.linux.dev,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC: DMA_PMD 00/22] DMA_PMD: PMD_SIZE-backed IO buffer pools
Date: Wed, 14 Oct 2026 19:28:16 +0200 [thread overview]
Message-ID: <8584c31e-fd93-4f1a-9929-e71c5d9ccd0f@nvidia.com> (raw)
In-Reply-To: <20261003212241.3432303-1-lrizzo@google.com>
Hi Luigi,
On 03.10.26 23:22, Luigi Rizzo wrote:
> Here is a subsystem called DMA_PMD on which I would like feedback on
> architecture, possible enhancements, or kernel components that could be
> reused to avoid duplication.
>
> I think it can be extremely useful for those affected by the HW/SW overhead
> of IOMMU (especially IOTLB thrashing, see [1]), or confidential computing,
> or preemptable VMs.
>
> The (not too exaggerated) pitch line is
>
> DMA_PMD has the performance of identity, guarantees that only IO buffers
> can ever have active IOMMU or IOTLB mappings, removes the bounce buffer
> overhead in confidential computing and preemptable VMs, and integrates
> smoothly with existing kernel APIs.
>
> === ARCHITECTURE
>
> DMA_PMD was initially designed to address IOTLB thrashing (details in [1]),
> but turned out to also resolve nicely the strict IOMMU overhead, and avoid
> the bounce buffer overhead in preemptible VMs and Confidential Computing.
>
> It works by combining several known techniques:
>
> - transparently feed allocators of device memory (skb_page_frag_refill(),
> dma_alloc_attrs(), pagepool, ...) with DMA_PMD pages, i.e. physically
> contiguous PMD_SIZE (2MB) pages mapped via PDE_SIZE IOMMU entries
>
> - heavy recycling of DMA_PMD pages (like pagepool) and lazy IOMMU unmapping
> (like DMA-FQ), BUT:
>
> - like strict IOMMU (DMA), safely release memory back to the kernel only
> after destroying all of its IOMMU mappings and a synchronous IOTLB flush
>
> - on allocation, DMA_PMD pages can be configured to be pinned in the host
> (hence suitable for preemptible VMs) and/or unencrypted (hence suitable
> for Confidential Computing), removing the need for bounce buffers
>
> - there are global and per-device optin /sys/device/.../dma_pmd_*
> and /proc/sys/net/core/tx_enable_dma_pmd
>
> NIC drivers can typically use dma_pmd with no modifications for rings,
> tx buffers, rx buffers (if they use pagepool), and rx headers. For tx
> headers, almost all drivers need changes (see later patches in the series)
> to implement cheap bounce buffers and avoid individual 4K mappings.
>
> The series has the following main components:
>
> - a sparse array (similar to pageblock_flags) to quickly attach metadata
> to a 2MB page without fiddling with the struct page. Cost is 128B per 2MB
> page used as an IO buffer, totally negligible.
>
> - dma_pmd_pool, a replacement for alloc_pages() that can be instantiated
> per-CPU or per receive queue. It handles the split of PMD_SIZE pages
> into order-N blocks, handles dma_map and unmap, and aggressively recycles
> entries. It is used to feed skb_page_frag_refill(), pagepool, and
> receive buffers for drivers that do not use pagepool.
> See [2] for "WHY NOT PAGEPOOL FOR TX AND EVERYTHING"
>
> - dma_pmd_arena, is another allocator backed by DMA_PMD pages and
> is used exclusively as the backend for dma_alloc_attrs().
> Used for longer-lived allocations (descriptor/completion rings,
> rx and tx header buffers)
>
> - glue code to hook DMA_PMD into pagepool [2], skb_page_frag_refill(),
> dma_alloc_attrs(), dma_map/unmap...
>
> - per-driver patches, where necessary (e.g. tx header buffers [3])
>
> === PERFORMANCE BENEFITS
>
> Your mileage may vary. Enabling the IOMMU may have no throughput
> impact, until it does when some system components (bus, IOTLB, CPU)
> become overloaded. Aside from throughput reduction, one interesting
> parameter is the effectiveness of the IOTLB. Here is a sample of SMMU
> performance counters for a large ARM system with 2x200G NICs doing
> bidirectional traffic:
>
> === DMA-FQ MODE (total throughput ~440Gbps)
> 25,757,488 smmuv3_pmcg_*/event=0x80/ IOTLB lookups
> 16,634,941 smmuv3_pmcg_*/event=0x81/ IOTLB misses
>
> === DMA_PMD on top of strict DMA (total throughput ~745Gbps)
> 22,693,218 smmuv3_pmcg_*/event=0x80/ IOTLB lookups
> 30,536 smmuv3_pmcg_*/event=0x81/ IOTLB misses
> (not a mistake, also lookups went down despite the higher rate
> because the tx side can use larger segments)
>
> The 2MB mappings made IOTLB misses almost non existent, because
> the working set is reduced by a factor of ~512.
>
> Note, the code has more verbose comments than I would like.
> Several of them are there to avoid Sashiko getting confused and
> flagging false positives.
>
> === NOTES
>
> [1] IOMMU IMPACT AND IOTLB THRASHING
> This is documented in more detail in Documentation/core-api/dma-pmd.rst
> but the compact version is below.
>
> There are three main costs involved with using the IOMMU:
> - CPU cost for dma map/unmap
> - CPU cost and latency for synchronous IOTLB flush (required for strong security)
> - IOTLB thrashing, shows up dramatically when the IO access pattern
> exceeds the IOTLB size, and IOMMU page walks slow down bus activity
> up to a point where we see over 30..60% throughput reduction just for
> this reason. Some relevant references
>
> https://lore.kernel.org/all/4b42f2eb-dc29-153e-ace9-5584ea2e5070@redhat.com/
> https://www.ncbi.nlm.nih.gov/pmc/articles/PMC10280580/
>
> Specifically, NICs access 4 or more pages per packet (descriptor queue,
> completion queue, rx or tx header, one or more buffers), with very little
> locality especially for data buffers and tx headers. Each queue has 1-4K
> entries, a fast NIC uses 16 or more queues per direction, so just the
> data buffers cover 32..128K pages. Using 4KB mappings makes the IOTLB
> ineffective, as shown by the performance counters shown earlier.
>
> [2] WHY NOT PAGEPOOL FOR TX AND EVERYTHING
> There is some overlap between pagepool and dma_pmd_pool in that both
> implement a cache, but pagepool is missing some important features:
>
> - pagepool does not handle splitting 2M pages in smaller chunks, or
> the mappings. That would need to be implemented (and is what dma_pmd_pool does)
>
> - pagepool's provided pages cannot be cleanly managed by
> get_page()/put_page(), which is what all the consumers of
> skb_page_frag_refill(). Fixing that would require dozen of changes
> with high risk of missing some paths.
>
> - even for the receive path, a provider for pagepool has more restrictions
> than alloc_pages-supplied memory, so if I wanted to wrap dma_pmd_pool
> as a provider I would have needed changes to the provider interface.
>
> - pagepool requires a device at allocation time, which is not known when
> skb_page_frag_refill() runs, hence the IOMMU mappings cannot be handled
> at allocation time.
>
> - page_pool_alloc_pages assumes a single NAPI consumer with BH disabled,
> whereas skb_page_frag_refill() runs from a preemptive context.
>
> - and last not least, we need to handle the dma_alloc_attrs() allocations
> which don't match pagepool API
>
> Of course all of the above could be modified, but the complexity
> would be similar to that of implementing dma_pmd_pool, and with a
> huge risk of breaking existing functionality or missing some path.
>
> [3] DRIVER CHANGES
>
> Most drivers need no change for rings, transmit buffers, or receive buffers
> (if they use pagepool). Tx headers are generally mapped on the fly and
> that is enough to trigger IOTLB thrashing, so most drivers need a small
> change to implement very cheap tx bounce buffers backed by DMA_PMD pages.
>
> We could avoid the bounce buffers using DMA_PMD for the skb->head region,
> but that memory is contiguous to skb_shinfo so it would be exposed to
> IO device access, which may be undesirable for security.
>
Thanks for the RFC. Here are my notes (some points rephrase what was already
said):
- On CoCo VMs it seems that the only way to opt in the IOMMU optimization is to
also opt in the copy avoidance which is not always desirable.
- Having the pool generic opens up more visibility from the untrusted host
side. Having device based pools at least isolates one device's memory from
the rest of the system.
- Also, device driver could help with provisioning just the right amount of
memory that is needed. And per device control also means that probably
you don't need to map everything RW to the IOMMU.
Thanks,
Dragos
next prev parent reply other threads:[~2026-10-14 17:28 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-03 21:22 [RFC: DMA_PMD 00/22] DMA_PMD: PMD_SIZE-backed IO buffer pools Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 01/22] iommu/dma: introduce CONFIG_DMA_PMD and metadata table Luigi Rizzo
2026-10-03 21:44 ` Randy Dunlap
2026-10-04 9:14 ` Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 02/22] iommu/dma: add DMA_PMD pool lifecycle and page recycle hook Luigi Rizzo
2026-10-10 2:59 ` kernel test robot
2026-10-03 21:22 ` [RFC: DMA_PMD 03/22] mm: Add split_page_compound() Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 04/22] iommu/dma: add DMA_PMD pool block allocation Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 05/22] iommu/dma: Global cap and shrinker for DMA_PMD pool memory Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 06/22] iommu/dma: reserve a per-domain IOVA window for DMA_PMD pages Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 07/22] iommu/dma: release DMA_PMD domain mappings on domain teardown Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 08/22] iommu/dma: use per-domain IOVA window to map DMA_PMD memory Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 09/22] iommu/dma: Add DMA_PMD arena allocator Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 10/22] driver core: Add per-device dma_pmd_* sysfs attributes Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 11/22] dma-mapping: Use DMA_PMD arena for dma_alloc_attrs() Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 12/22] net/core: Use per-CPU DMA_PMD pools for skb_page_frag_refill() Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 13/22] net/core: Use DMA_PMD for page_pool memory Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 14/22] iommu/dma: Support decrypted and pinned DMA_PMD pages Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 15/22] iommu/dma: Add background page scrubber for DMA_PMD pools Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 16/22] iommu/dma: Add per-NUMA-node PMD page reservoir Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 17/22] net/gve: Use DMA_PMD memory for RX buffers Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 18/22] net/gve: Use DMA_PMD memory for tx header bounce buffers Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 19/22] net/mlx5e: " Luigi Rizzo
2026-10-14 17:22 ` Dragos Tatulea
2026-10-14 17:50 ` Dragos Tatulea
2026-10-14 18:28 ` Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 20/22] net/idpf: " Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 21/22] net/bnxt: " Luigi Rizzo
2026-10-03 21:22 ` [RFC: DMA_PMD 22/22] iommu/dma: Add DMA_PMD statistics and debugfs Luigi Rizzo
2026-10-11 9:02 ` [RFC: DMA_PMD 00/22] DMA_PMD: PMD_SIZE-backed IO buffer pools Pranjal Shrivastava
2026-10-12 13:51 ` David Hildenbrand (Arm)
2026-10-12 14:45 ` Luigi Rizzo
2026-10-12 19:43 ` David Hildenbrand (Arm)
2026-10-13 10:42 ` Robin Murphy
2026-10-14 10:47 ` David Hildenbrand (Arm)
2026-10-14 11:05 ` Luigi Rizzo
2026-10-12 14:49 ` Mostafa Saleh
2026-10-12 15:02 ` Luigi Rizzo
2026-10-14 17:28 ` Dragos Tatulea [this message]
2026-10-14 18:14 ` Luigi Rizzo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8584c31e-fd93-4f1a-9929-e71c5d9ccd0f@nvidia.com \
--to=dtatulea@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=aleksander.lobakin@intel.com \
--cc=anthony.l.nguyen@intel.com \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=davem@davemloft.net \
--cc=david@kernel.org \
--cc=driver-core@lists.linux.dev \
--cc=edumazet@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=hawk@kernel.org \
--cc=hch@lst.de \
--cc=hramamurthy@google.com \
--cc=ilias.apalodimas@linaro.org \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=joshwash@google.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lrizzo@google.com \
--cc=m.szyprowski@samsung.com \
--cc=michael.chan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pavan.chebbi@broadcom.com \
--cc=przemyslaw.kitszel@intel.com \
--cc=rafael@kernel.org \
--cc=rizzo.unipi@gmail.com \
--cc=robin.murphy@arm.com \
--cc=saeedm@nvidia.com \
--cc=tariqt@nvidia.com \
--cc=vbabka@kernel.org \
--cc=will@kernel.org \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox