On Wed, May 20, 2026 at 06:20:13PM -0400, Michael S. Tsirkin wrote:
> When a guest reports free pages to the hypervisor via virtio-balloon's
> free page reporting, the host typically zeros those pages when reclaiming
> their backing memory (e.g., via MADV_DONTNEED on anonymous mappings).
> When the guest later reallocates those pages, the kernel zeros them
> again, redundantly.
FYI Sashiko reported a couple of issues. Mostly false positives but
I tweaked commit log to make it clearer. But also a couple of
real issues. So far I have this diff on top:
--->
Changes from v8 to v9 candidate (code only):
1. mm/mempolicy.c (patch 1: mm: mempolicy: fix interleave index calculation)
Combine vm_pgoff and VMA offset into a single expression before
shifting, fixing carry loss for file-backed VMAs with unaligned
vm_pgoff.
2. mm/memory-failure.c (patch 2: mm: memory-failure: serialize
TestSetPageHWPoison with zone->lock)
Wrap ClearPageHWPoison in retry path with zone->lock too.
3. mm/huge_memory.c (patch 19: mm: use __GFP_ZERO in vma_alloc_anon_folio_pmd)
Fix stale comment: "folio_zero_user writes" -> "page zeroing".
4. mm/page_reporting.c (patch 4: mm: page_reporting: allow driver to set batch
capacity)
Drop rounddown_pow_of_two: compiler cannot optimize division
by runtime variable anyway, and rounding halves batch size for
non-power-of-2 capacity values.
Commit log improvements (no code change):
- Patch 1: rewritten to explain new single-expression formula (fixes patch 1)
- Patch 2: mention ClearPageHWPoison in retry path (fixes patch 2)
- Patch 4: drop "rounded down to a power of 2" (fixes patch 4)
- Patch 10: "stub" wording simplified (fixes patch 10)
- Patch 22: note PG_zeroed hint loss is harmless (fixes patch 22)
- Patch 23: add PowerPC note (fixes patch 23)
- Patch 28: explain DEVICE_INIT_ON_INFLATE is a follow-up (fixes patch 28)
- Patch 29: explain flush over-reporting is by design (fixes patch 29)
- Patch 33: note __SetPageZeroed is safe on frozen pages (fixes patch 33)
- Patch 36: note __SetPageZeroed is safe on balloon-owned pages (fixes patch 36)
---
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9845c920c29c..4978d34532ea 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1358,7 +1358,7 @@ static struct folio *vma_alloc_anon_folio_pmd(struct
vm_area_struct *vma,
/*
* The memory barrier inside __folio_mark_uptodate makes sure that
- * folio_zero_user writes become visible before the set_pmd_at()
+ * page zeroing becomes visible before the set_pmd_at()
* write.
*/
__folio_mark_uptodate(folio);
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a6b61172dd13..d106f2c135c7 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2426,7 +2426,9 @@ int memory_failure(unsigned long pfn, int flags)
} else {
/* We lost the race, try again */
if (retry) {
+ spin_lock_irqsave(&zone->lock,
mf_flags);
ClearPageHWPoison(p);
+ spin_unlock_irqrestore(&zone->lock,
mf_flags);
retry = false;
goto try_again;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index ea3043e0075b..f573ff32e94d 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2048,9 +2048,9 @@ struct mempolicy *get_vma_policy(struct vm_area_struct
*vma,
pol = get_task_policy(current);
if (pol->mode == MPOL_INTERLEAVE ||
pol->mode == MPOL_WEIGHTED_INTERLEAVE) {
- *ilx += vma->vm_pgoff >> order;
- *ilx += (addr >> (PAGE_SHIFT + order)) -
- (vma->vm_start >> (PAGE_SHIFT + order));
+ *ilx += (vma->vm_pgoff +
+ (addr >> PAGE_SHIFT) -
+ (vma->vm_start >> PAGE_SHIFT)) >> order;
}
return pol;
}
diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index 8b278a494ea5..3f584f538c68 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -443,9 +443,6 @@ int page_reporting_register(struct page_reporting_dev_info
*prdev)
if (!prdev->capacity || prdev->capacity > PAGE_REPORTING_CAPACITY)
prdev->capacity = PAGE_REPORTING_CAPACITY;
- /* Power of 2 so division by capacity in the budget calc is cheap */
- prdev->capacity = rounddown_pow_of_two(prdev->capacity);
-
/* initialize state and work structures */
atomic_set(&prdev->state, PAGE_REPORTING_IDLE);
INIT_DELAYED_WORK(&prdev->work, &page_reporting_process);