]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm/percpu-km: fix bitmap overflow and accounting in pcpu_create_chunk()
authorZi Yan <ziy@nvidia.com>
Thu, 9 Jul 2026 19:12:01 +0000 (15:12 -0400)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 21 Jul 2026 00:41:27 +0000 (17:41 -0700)
In pcpu_create_chunk(), nr_pages is the total contiguous backing
allocation, i.e., nr_units * pcpu_unit_pages, but pcpu_chunk_populated()
uses it to set chunk->populated, whose size is pcpu_unit_pages, bitmap.
Since bit N in chunk->populated means page offset N inside every unit is
backed.  When nr_units > 1, the function writes beyond chunk->populated.
Fix it by using chunk->nr_pages.

It also fixes the global pcpu_nr_empty_pop_pages accounting, since
pcpu_balance_free() only iterates up to chunk->nr_pages.

Commit a63d4ac4ab609 ("percpu: make percpu-km set chunk->populated bitmap
properly") introduced the bitmap overflow issue.  Later, commit
b539b87fed37f ("percpu: implmeent pcpu_nr_empty_pop_pages and
chunk->nr_populated") added pcpu_nr_empty_pop_pages and caused the
accounting issue.

Link: https://lore.kernel.org/20260709-fix-pcpu_create_chunk-in-percpu-km-v1-1-1f64745a84cc@nvidia.com
Fixes: a63d4ac4ab609 ("percpu: make percpu-km set chunk->populated bitmap properly")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260703-keep-subpage-private-zero-at-free-v2-0-2970fe777dd6%40nvidia.com?part=1
Assisted-by: Codex:GPT-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
Acked-by: Dennis Zhou <dennis@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/percpu-km.c

index 4efa74a495cb6bb1c42550ebc3a8b7a6f9eadf18..dc096b5a6ce40c13b4556e0d2b6bb041effd3d4b 100644 (file)
@@ -75,7 +75,7 @@ static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp)
        chunk->base_addr = page_address(pages);
 
        spin_lock_irqsave(&pcpu_lock, flags);
-       pcpu_chunk_populated(chunk, 0, nr_pages);
+       pcpu_chunk_populated(chunk, 0, chunk->nr_pages);
        spin_unlock_irqrestore(&pcpu_lock, flags);
 
        pcpu_stats_chunk_alloc();