From: sashiko-bot@kernel.org
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>,
"Jens Axboe" <axboe@kernel.dk>,
"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>,
"Matthew Wilcox" <willy@infradead.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"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>,
"Alexander Lobakin" <aleksander.lobakin@intel.com>,
linux-mm@kvack.org
Subject: Re: [RFC PATCH v2 03/25] iommu/dma: Add per-NUMA-node PISA page reservoir
Date: Tue, 10 Nov 2026 23:12:05 +0000 [thread overview]
Message-ID: <sashiko-outbox-207858@kernel.org> (raw)
In-Reply-To: <20261109182533.3594984-4-lrizzo@google.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] iommu/dma: pisa_reservoir_pop() schedules refill worker
before backoff check
- [Medium] iommu/dma: fs_reclaim lock inversion on pisa_meta_mutex in
__pisa_page_alloc()
--
commit 6907cf09179e9a96def9072a9cbbe4eddf0cc46c
Author: Luigi Rizzo <lrizzo@google.com>
iommu/dma: Add per-NUMA-node PISA page reservoir
This commit adds a per-NUMA-node reservoir of pre-allocated PISA pages to
serve non-blocking allocations, refilled and trimmed asynchronously by
per-node work items.
> diff --git a/drivers/iommu/pisa-node.c b/drivers/iommu/pisa-node.c
> new file mode 100644
> index 0000000000000..524f0d4457ad7
> --- /dev/null
> +++ b/drivers/iommu/pisa-node.c
[ ... ]
> +/* Allocate a PISA page from the buddy allocator and initialize its metadata. */
> +static struct pisa_meta *__pisa_page_alloc(gfp_t gfp, int nid, bool can_block,
> + bool *clean)
> +{
> + struct pisa_meta *meta;
> + unsigned int memflags;
> + struct page *page;
> +
> + if (unlikely(!static_branch_unlikely(&pisa_key))) {
> + if (!can_block || (gfp & (__GFP_FS | __GFP_IO)) != (__GFP_FS | __GFP_IO) ||
> + pisa_meta_init())
> + return ERR_PTR(-EAGAIN);
> + }
> +
> + /*
> + * Long-lived active pages must be unmovable, lowmem, non-compound, and
> + * must not dip into emergency reserves or trigger OOM/warnings.
> + */
> + gfp &= ~(__GFP_COMP | __GFP_HIGHMEM | __GFP_MOVABLE);
> + gfp |= __GFP_NOWARN | __GFP_NOMEMALLOC | (can_block ? __GFP_RETRY_MAYFAIL : __GFP_NORETRY);
> +
> + if (can_block)
> + memflags = pisa_memalloc_save(gfp);
> + page = alloc_pages_node(nid, gfp, PISA_ORDER);
> + if (!page) {
> + if (can_block)
> + memalloc_flags_restore(memflags);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + /* Ensure the metadata chunk for this PFN is populated. */
> + if (unlikely(pisa_meta_ensure_pfn(page_to_pfn(page), can_block))) {
[Severity: Medium]
Can this invert the lock order between pisa_meta_mutex and fs_reclaim when
called under GFP_NOFS, GFP_NOIO, or a memalloc_nofs_save() /
memalloc_noio_save() scope?
pisa_meta_init(), pisa_meta_memory_cb(), and GFP_KERNEL calls to
pisa_meta_ensure_pfn() perform GFP_KERNEL allocations while holding
pisa_meta_mutex, establishing pisa_meta_mutex -> fs_reclaim.
Here, can_block is gfpflags_allow_blocking(gfp), which is true for GFP_NOFS
and GFP_NOIO. Although pisa_memalloc_save(gfp) sets PF_MEMALLOC_NOFS or
PF_MEMALLOC_NOIO, __pisa_page_alloc() still passes can_block = true to
pisa_meta_ensure_pfn(), which acquires pisa_meta_mutex when the metadata
page table is not yet populated:
drivers/iommu/pisa-meta.c:pisa_meta_ensure_pfn() {
...
if (can_block && !pisa_meta_pte((unsigned long)pisa_meta_array + (idx << PAGE_SHIFT))) {
int err;
mutex_lock(&pisa_meta_mutex);
err = pisa_meta_prealloc(pisa_meta_array, pisa_meta_nframes, pfn, pfn + 1);
mutex_unlock(&pisa_meta_mutex);
...
}
In addition, the pisa_meta_init() check above tests raw gfp rather than
current_gfp_context(gfp), so a caller inside a memalloc_nofs_save() or
memalloc_noio_save() scope passing GFP_KERNEL will also take pisa_meta_mutex:
CPU0 CPU1
---- ----
lock(fs_reclaim)
mutex_lock(&pisa_meta_mutex)
mutex_lock(&pisa_meta_mutex)
lock(fs_reclaim)
*** DEADLOCK ***
CPU0: fs/io path (holding lock waited on by reclaim) -> pisa_reservoir_pop()
-> __pisa_page_alloc() -> pisa_meta_ensure_pfn() / pisa_meta_init()
CPU1: pisa_node_work_fn() -> pisa_meta_init() -> kvcalloc(..., GFP_KERNEL)
Passing current_gfp_context(gfp) into gfp at entry and only allowing the
mutex-taking paths when (gfp & (__GFP_FS | __GFP_IO)) == (__GFP_FS | __GFP_IO)
would avoid this lock inversion.
[ ... ]
> +/* Refill node @nid's reservoir up to pisa_reservoir_max pre-zeroed PISA pages. */
> +static void pisa_reservoir_refill_node(int nid)
> +{
> + struct pisa_node *res = &pisa_nodes[nid];
> +
> + while (res->nr_pages < READ_ONCE(pisa_reservoir_max)) {
> + struct pisa_meta *meta;
> + unsigned long flags;
> + bool clean;
> +
> + meta = __pisa_page_alloc(GFP_KERNEL | __GFP_THISNODE, nid, true, &clean);
> + if (IS_ERR(meta))
> + break;
[ ... ]
> +struct pisa_meta *pisa_reservoir_pop(int nid, gfp_t gfp, bool *clean)
> +{
> + bool can_block = gfpflags_allow_blocking(gfp);
> + unsigned int max = READ_ONCE(pisa_reservoir_max);
> + struct pisa_meta *meta;
> +
> + nid = pisa_sanitize_nid(nid);
> + if (max) {
> + meta = pisa_reservoir_pop_node(nid, max);
> + if (meta) {
> + *clean = true;
> + return meta;
> + }
> + /* Empty: pop_node() only schedules after a successful pop. */
> + pisa_schedule_reservoir_node(nid);
> + }
> +
> + /* Back off briefly on GFP_ATOMIC if previous allocation on @nid failed. */
> + if (!can_block && time_before(jiffies, READ_ONCE(pisa_nodes[nid].next_alloc)))
> + return ERR_PTR(-EAGAIN);
[Severity: Medium]
Does calling pisa_schedule_reservoir_node(nid) before checking
pisa_nodes[nid].next_alloc defeat the backoff for the refill work item when
the reservoir is empty?
When order-9 allocations on nid are failing under memory pressure or
fragmentation, a GFP_ATOMIC miss sets pisa_nodes[nid].next_alloc to back off
for 10ms. However, every subsequent GFP_ATOMIC call to pisa_reservoir_pop()
during that backoff window still queues pisa_nodes[nid].work before hitting
the next_alloc check, and pisa_reservoir_refill_node() immediately breaks
out on __pisa_page_alloc() failure, allowing softirq callers to continuously
re-queue the worker and trigger repeated GFP_KERNEL | __GFP_RETRY_MAYFAIL
compaction attempts.
Checking next_alloc before pisa_schedule_reservoir_node(nid) (or having
refill failure also update next_alloc) would keep the worker from thrashing
during backoff.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109182533.3594984-1-lrizzo@google.com?part=3
next prev parent reply other threads:[~2026-11-10 23:12 UTC|newest]
Thread overview: 108+ 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-08 11:25 ` kernel test robot
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-17 17:11 ` Luigi Rizzo
2026-10-22 20:12 ` Jason Gunthorpe
2026-10-22 21:51 ` Luigi Rizzo
2026-10-23 14:01 ` Jason Gunthorpe
2026-10-23 14:30 ` Luigi Rizzo
2026-10-23 14:50 ` Jason Gunthorpe
2026-10-23 15:12 ` Luigi Rizzo
2026-10-23 17:27 ` Jakub Kicinski
2026-10-23 20:22 ` Luigi Rizzo
2026-11-03 8:09 ` Christoph Hellwig
2026-11-03 9:13 ` Luigi Rizzo
2026-11-03 15:10 ` Jason Gunthorpe
2026-11-06 17:21 ` Naman Gulati
2026-11-06 17:30 ` Jason Gunthorpe
2026-11-06 18:00 ` Naman Gulati
2026-11-06 18:07 ` Jason Gunthorpe
2026-11-06 18:17 ` Naman Gulati
2026-11-06 18:43 ` Jason Gunthorpe
2026-11-06 19:01 ` Luigi Rizzo
2026-11-06 19:11 ` Naman Gulati
2026-10-12 14:49 ` Mostafa Saleh
2026-10-12 15:02 ` Luigi Rizzo
2026-10-14 17:28 ` Dragos Tatulea
2026-10-14 18:14 ` Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 00/25] PISA: Pre-mapped IOVA Superpage Allocator for DMA and CoCo Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 01/25] iommu/dma: Introduce CONFIG_PISA and metadata table Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 02/25] iommu/dma: Add PISA allocator lifecycle and page recycle hook Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 03/25] iommu/dma: Add per-NUMA-node PISA page reservoir Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot [this message]
2026-11-09 18:25 ` [RFC PATCH v2 04/25] iommu/dma: Add PISA block allocation Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 05/25] iommu/dma: Add global cap and shrinker for PISA pages Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 06/25] iommu/dma: Reserve a per-domain IOVA window " Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 07/25] iommu/dma: Release PISA domain mappings on domain teardown Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 08/25] iommu/dma: Use per-domain IOVA window to map PISA memory Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 09/25] driver core: Add per-device pisa_* sysfs attributes for PISA optin Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 10/25] iommu/dma: Use PISA for coherent DMA allocations Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 11/25] iommu/dma: Add per-CPU block caches to PISA allocators Luigi Rizzo
2026-11-10 23:12 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 12/25] net/core: Use per-node PISA allocators for skb_page_frag_refill() Luigi Rizzo
2026-11-10 23:50 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 13/25] net/core: Use PISA for page_pool memory Luigi Rizzo
2026-11-09 18:25 ` [RFC PATCH v2 14/25] iommu/dma: Support decrypted PISA pages Luigi Rizzo
2026-11-11 0:19 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 15/25] iommu/dma: Add background page scrubber for PISA allocators Luigi Rizzo
2026-11-11 0:37 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 16/25] mm/slub: Add SLAB_CACHE_PISA_RO for PISA-backed slab caches Luigi Rizzo
2026-11-11 1:03 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 17/25] net: Allocate small skb heads from PISA Luigi Rizzo
2026-11-11 1:33 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 18/25] iommu/dma: Migrate user pages into PISA for TX zerocopy Luigi Rizzo
2026-11-11 2:41 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 19/25] iommu/dma: Stop recycling old PISA pages when allocator waste is high Luigi Rizzo
2026-11-11 2:57 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 20/25] net/libeth: Use GFP_KERNEL when pre-filling RX rings Luigi Rizzo
2026-11-11 3:13 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 21/25] net/gve: " Luigi Rizzo
2026-11-11 3:22 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 22/25] net/gve: Use PISA memory for RX buffers Luigi Rizzo
2026-11-11 3:43 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 23/25] block, mm, iommu/dma: Support PISA for disk I/O and scrub migration Luigi Rizzo
2026-11-11 4:16 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 24/25] Documentation: Add PISA architecture documentation Luigi Rizzo
2026-11-11 4:24 ` sashiko-bot
2026-11-09 18:25 ` [RFC PATCH v2 25/25] iommu/dma: Add PISA statistics and debugfs Luigi Rizzo
2026-11-11 4:37 ` sashiko-bot
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=sashiko-outbox-207858@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=aleksander.lobakin@intel.com \
--cc=axboe@kernel.dk \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=davem@davemloft.net \
--cc=david@kernel.org \
--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=joro@8bytes.org \
--cc=joshwash@google.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=lrizzo@google.com \
--cc=m.szyprowski@samsung.com \
--cc=pabeni@redhat.com \
--cc=rafael@kernel.org \
--cc=rizzo.unipi@gmail.com \
--cc=robin.murphy@arm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vbabka@kernel.org \
--cc=will@kernel.org \
--cc=willemb@google.com \
--cc=willy@infradead.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.