All of lore.kernel.org
 help / color / mirror / Atom feed
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 11/25] iommu/dma: Add per-CPU block caches to PISA allocators
Date: Tue, 10 Nov 2026 23:12:17 +0000	[thread overview]
Message-ID: <sashiko-outbox-207866@kernel.org> (raw)
In-Reply-To: <20261109182533.3594984-12-lrizzo@google.com>

Thank you for your contribution! Sashiko AI review found 4 potential
issues to consider:
- [Medium] iommu/dma: cross-node per-CPU cache refill in
  pisa_alloc_bulk()
- [Medium] iommu/dma: hardcoded order 3 in test_gfp_pisa() fails on
  16K/64K pages
- [Low] iommu/dma: changelog omits pisa_page_can_recycle() and
  pisa.compact
- [Low] iommu/dma: short allocation in pisa_pcp_alloc() on poisoned
  block
--

commit 6d45ca2b93f2e0d3d72f8ae4375bcf8901944ad1
Author: Luigi Rizzo <lrizzo@google.com>

> iommu/dma: Add per-CPU block caches to PISA allocators
>
> Every block allocation and free takes the allocator's lock. Highly
> concurrent users e.g. socket tx fragments, can cause significant lock
> contention.
>
> Add pisa_enable_pcp(), an opt-in per-CPU front cache, similar
> to the page allocator's per-CPU lists:
>
> - Each per-CPU cache keeps up to 64 free blocks, and refills it from
>   the main allocator in batches of 32.
> - returned blocks belonging to the local NUMA node are kept in the local
>   cache.
> - returned blocks belonging to a remote NUMA node are returned to the
>   proper per-node allocator.
> The cache is fully integrated with the shrinker and CPU offlining to
> drain the cache.
>
> Enable per-CPU caches for the per-node order-0 RW and SKB_FRAG_PAGE_ORDER
> RO allocators.
>
> Signed-off-by: Luigi Rizzo <lrizzo@google.com>

[Severity: Low]
This isn't a bug, but this patch also adds and exports
pisa_page_can_recycle(), the pisa.compact module parameter, and the
per-allocator block and page accounting used for soft compaction, none of
which are mentioned in the commit message.

> diff --git a/drivers/iommu/pisa-alloc.c b/drivers/iommu/pisa-alloc.c
> index 25e4645310678..913706a503341 100644
> --- a/drivers/iommu/pisa-alloc.c
> +++ b/drivers/iommu/pisa-alloc.c

[ ... ]

> +/* Allocate @nr_pages blocks through this CPU's cache, refilling in batches on miss. */
> +static unsigned long pisa_pcp_alloc(struct pisa_alloc *pa, gfp_t gfp, unsigned long nr_pages,
> +				    struct page **page_array, bool frozen)
> +{
> +	unsigned int pcp_batch = READ_ONCE(pisa_pcp_batch);
> +	unsigned long got, n, i, j;
> +
> +	got = pisa_pcp_pop(pa, nr_pages, page_array);
> +	if (got < nr_pages) {
> +		if (nr_pages - got >= pcp_batch) {
> +			got += __pisa_alloc_bulk(pa, gfp, nr_pages - got,
> +						 page_array + got, false, true);
> +		} else {
> +			struct page *batch[PISA_PCP_BATCH];
> +
> +			n = __pisa_alloc_bulk(pa, gfp, pcp_batch, batch, false, true);
> +			for (i = 0; i < n && got < nr_pages; i++)
> +				page_array[got++] = batch[i];
> +			if (i < n)
> +				pisa_pcp_push(pa, batch + i, n - i);
> +		}
> +	}
> +
> +	for (i = j = 0; i < got; i++) {
> +		struct page *block = page_array[i];
> +
> +		page_array[i] = NULL;
> +		/* Poisoned while cached: leak it, as pisa_scan_bitmap() does. */
> +		if (pisa_block_poisoned(pa, block))
> +			continue;
> +		pisa_block_prep(block);
> +		if (want_init_on_alloc(gfp)) {
> +			memset(page_address(block), 0, PAGE_SIZE << pa->order);
> +			if (frozen) /* Order zeroing before caller publishes the page. */
> +				smp_wmb();
> +		}
> +		if (!frozen)
> +			page_ref_unfreeze(block, 1);
> +		page_array[j++] = block;
> +	}
> +	return j;
> +}
> +
>  /**
>   * pisa_alloc_bulk - Allocate up to @nr_pages blocks from @pa
>   * @pa: Allocator to allocate from
> @@ -681,11 +952,16 @@ unsigned long pisa_alloc_bulk(struct pisa_alloc *pa, gfp_t gfp,
>  			i++;
>  			continue;
>  		}
> +
>  		/* Fill the run of @n NULL entries at @i. */
>  		for (n = 1; i + n < nr_pages && !page_array[i + n]; n++)
>  			;
> -		got = __pisa_alloc_bulk(pa, gfp, n, page_array + i,
> -					want_init_on_alloc(gfp), frozen);
> +		/* Pairs with smp_store_release() in pisa_enable_pcp(). */
> +		if (smp_load_acquire(&pa->pcp))
> +			got = pisa_pcp_alloc(pa, gfp, n, page_array + i, frozen);
> +		else
> +			got = __pisa_alloc_bulk(pa, gfp, n, page_array + i,
> +						want_init_on_alloc(gfp), frozen);
>  		i += got;
>  		if (got < n)
>  			break;

[Severity: Low]
If a block popped from pa->pcp was poisoned while cached, does
pisa_pcp_alloc() return fewer than n blocks without refilling a
replacement?  Unlike pisa_scan_bitmap(), skipping the poisoned block after
the refill stage causes pisa_alloc_bulk() to see got < n and abort the
allocation early even when healthy blocks are available.

[ ... ]

> @@ -876,6 +1158,17 @@ bool __pisa_free_page(struct page *page)
>  	if (want_init_on_free())
>  		memset(page_address(page), 0, PAGE_SIZE << pa->order);
>  
> +	/* Pairs with cmpxchg_release() in pisa_enable_pcp(). */
> +	if (smp_load_acquire(&pa->pcp) && pa->nid == numa_mem_id() &&
> +	    page_to_nid(page) == numa_mem_id()) {
> +		if (pisa_page_can_recycle(page)) {
> +			pisa_pcp_push(pa, &page, 1);
> +			return true;
> +		}
> +		if (this_cpu_read(pa->pcp->count))
> +			pisa_pcp_drain_cpu(pa, raw_smp_processor_id());
> +	}

[Severity: Medium]
Can pisa_alloc_bulk() -> pisa_pcp_alloc() populate pa->pcp on a CPU where
numa_mem_id() != pa->nid?

__pisa_free_page() only pushes freed blocks to or compact-drains pa->pcp
when pa->nid == numa_mem_id(), but pisa_alloc_bulk() calls
pisa_pcp_alloc() without checking whether the current CPU belongs to
pa->nid (and __pisa_alloc_bulk() can also sleep and migrate the task
before pisa_pcp_push() runs).

On a multi-node NUMA system, a cross-node allocation refills 32 blocks and
leaves up to 31 blocks cached in that remote CPU's pa->pcp, where normal
frees never compact-drain them and CPUs on pa->nid never pop them, pinning
their backing 2MB PISA pages in pa->blocks_in_use.  This also causes
test_pcp_cache() and test_alloc_and_recycle() in drivers/iommu/pisa-kunit.c
to fail KUNIT_EXPECT_PTR_EQ(test, p2, p1) whenever the KUnit kthread runs
on a CPU with numa_mem_id() != first_memory_node: p1 = pisa_alloc(pa, ...)
refills 32 blocks into the remote CPU's pa->pcp and returns batch[0],
__free_page(p1) bypasses pa->pcp and returns p1 to the bitmap, and
p2 = pisa_alloc(pa, ...) pops batch[31] from pa->pcp instead of p1.

> diff --git a/drivers/iommu/pisa-kunit.c b/drivers/iommu/pisa-kunit.c
> index 72ee8986b4802..5bbb540eb505e 100644
> --- a/drivers/iommu/pisa-kunit.c
> +++ b/drivers/iommu/pisa-kunit.c

[ ... ]

> +static void test_gfp_pisa(struct kunit *test)
> +{

[ ... ]

> +	p_ro = alloc_pages(GFP_KERNEL | __GFP_COMP | __GFP_PISA_RO, 3);
> +	KUNIT_ASSERT_NOT_NULL(test, p_ro);
> +	if (p_ro) {
> +		KUNIT_EXPECT_TRUE(test, is_pisa_page(p_ro));
> +		KUNIT_EXPECT_EQ(test, pisa_meta_of_pfn(page_to_pfn(p_ro))->prot,
> +				IOMMU_READ);
> +		__free_pages(p_ro, 3);
> +	}

[Severity: Medium]
Should test_gfp_pisa() pass SKB_FRAG_PAGE_ORDER (or 2) instead of
hardcoding order 3?  pisa_init() only creates read-only per-node
allocators for orders 2 and SKB_FRAG_PAGE_ORDER, and on arm64 with 16KB or
64KB base pages SKB_FRAG_PAGE_ORDER is 1 or 0, so order 3 has no read-only
PISA allocator and falls back to the buddy allocator, failing
is_pisa_page(p_ro).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109182533.3594984-1-lrizzo@google.com?part=11


  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
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 [this message]
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-207866@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.