* [PATCH V4 0/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
@ 2026-03-05 5:31 Anshuman Khandual
2026-03-05 5:31 ` [PATCH V4 1/2] " Anshuman Khandual
2026-03-05 5:31 ` [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping Anshuman Khandual
0 siblings, 2 replies; 7+ messages in thread
From: Anshuman Khandual @ 2026-03-05 5:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Anshuman Khandual, Catalin Marinas, Will Deacon, Ryan Roberts,
David Hildenbrand, Yang Shi, Christoph Lameter, linux-kernel
This series enables batched TLB flush in unmap_hotplug_range() which avoids
individual page TLB flush for potential CONT blocks in linear mapping while
also improving performance due to range based TLB operation along with less
synchronization barrier instructions.
It also now rejects memory removal that might split a leaf entry in kernel
mapping, which would have otherwise required re-structuring using the break
before make (BBM) semantics. But kernel cannot tolerate BBM, so remapping to
fine grained leaves would not be possible on systems without BBML2_NOABORT.
This series applies on 7.0-rc2 and tested on KVM guest.
Changes in V4:
Accommodated all comments from David H
- Dropped 'size' in can_unmap_without_split()
- Added BUILD_BUG_ON() for SPARSEMEM_VMEMMAP in can_unmap_without_split()
- Added unified comment in addr_splits_kernel_leaf()
- Replaced ALIGNED_DOWN() with IS_ALIGNED()
- Dropped all PXX_SIZE comments in addr_splits_kernel_leaf()
- Dropped the comment in unmap_hotplug_range()
- Dropped the comments about TLB flush being essential for freeing memory
- Replaced the comments regarding CONT blocks
- Replaced the comments as unmap_hotplug_range() flushes TLB for !free_mapped
- Dropped "Fixes:" and "Closes:" tag from [PATCH 2/2], added "Link:" instead
Changes in V3:
https://lore.kernel.org/all/20260224062423.972404-1-anshuman.khandual@arm.com/
- Fixed some typos in the commit message for [PATCH 2/2]
- Dropped copying stable@vger.kernel.org per Ryan
Changes in V2:
https://lore.kernel.org/all/20260203130348.612150-1-anshuman.khandual@arm.com/
- Renamed split_kernel_leaf_boundary() as addr_splits_kernel_leaf()
- Dropped pte_valid()/pmd_leaf() before checking pte_cont()/pmd_cont()
- Changed and dropped variables in can_unmap_without_split()
- Moved can_unmap_without_split() after boot memory check
- Renamed 'prevent_bootmem' as 'prevent_memory' across the board
- Updated commit message in both patches
Changes in V1:
- https://lore.kernel.org/all/20260202042617.504183-1-anshuman.khandual@arm.com/
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: Christoph Lameter <cl@gentwo.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Anshuman Khandual (2):
arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
arm64/mm: Reject memory removal that splits a kernel leaf mapping
arch/arm64/mm/mmu.c | 170 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 148 insertions(+), 22 deletions(-)
--
2.30.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH V4 1/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
2026-03-05 5:31 [PATCH V4 0/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range() Anshuman Khandual
@ 2026-03-05 5:31 ` Anshuman Khandual
2026-03-05 12:39 ` David Hildenbrand (Arm)
2026-03-05 5:31 ` [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping Anshuman Khandual
1 sibling, 1 reply; 7+ messages in thread
From: Anshuman Khandual @ 2026-03-05 5:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Anshuman Khandual, Catalin Marinas, Will Deacon, Ryan Roberts,
David Hildenbrand, Yang Shi, Christoph Lameter, linux-kernel,
stable
During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.
This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().
Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.
Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.
This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm64/mm/mmu.c | 46 +++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a6a00accf4f9..f7ccda22d39e 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1458,10 +1458,18 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
WARN_ON(!pte_present(pte));
__pte_clear(&init_mm, addr, ptep);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /*
+ * CONT blocks are not supported in the vmemmap
+ */
+ WARN_ON(pte_cont(pte));
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
free_hotplug_page_range(pte_page(pte),
PAGE_SIZE, altmap);
+ }
+ /*
+ * unmap_hotplug_range() flushes TLB for !free_mapped
+ */
} while (addr += PAGE_SIZE, addr < end);
}
@@ -1482,15 +1490,18 @@ static void unmap_hotplug_pmd_range(pud_t *pudp, unsigned long addr,
WARN_ON(!pmd_present(pmd));
if (pmd_sect(pmd)) {
pmd_clear(pmdp);
-
- /*
- * One TLBI should be sufficient here as the PMD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /*
+ * CONT blocks are not supported in the vmemmap
+ */
+ WARN_ON(pmd_cont(pmd));
+ flush_tlb_kernel_range(addr, addr + PMD_SIZE);
free_hotplug_page_range(pmd_page(pmd),
PMD_SIZE, altmap);
+ }
+ /*
+ * unmap_hotplug_range() flushes TLB for !free_mapped
+ */
continue;
}
WARN_ON(!pmd_table(pmd));
@@ -1515,15 +1526,14 @@ static void unmap_hotplug_pud_range(p4d_t *p4dp, unsigned long addr,
WARN_ON(!pud_present(pud));
if (pud_sect(pud)) {
pud_clear(pudp);
-
- /*
- * One TLBI should be sufficient here as the PUD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
free_hotplug_page_range(pud_page(pud),
PUD_SIZE, altmap);
+ }
+ /*
+ * unmap_hotplug_range() flushes TLB for !free_mapped
+ */
continue;
}
WARN_ON(!pud_table(pud));
@@ -1553,6 +1563,7 @@ static void unmap_hotplug_p4d_range(pgd_t *pgdp, unsigned long addr,
static void unmap_hotplug_range(unsigned long addr, unsigned long end,
bool free_mapped, struct vmem_altmap *altmap)
{
+ unsigned long start = addr;
unsigned long next;
pgd_t *pgdp, pgd;
@@ -1574,6 +1585,9 @@ static void unmap_hotplug_range(unsigned long addr, unsigned long end,
WARN_ON(!pgd_present(pgd));
unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
} while (addr = next, addr < end);
+
+ if (!free_mapped)
+ flush_tlb_kernel_range(start, end);
}
static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
--
2.30.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping
2026-03-05 5:31 [PATCH V4 0/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range() Anshuman Khandual
2026-03-05 5:31 ` [PATCH V4 1/2] " Anshuman Khandual
@ 2026-03-05 5:31 ` Anshuman Khandual
2026-03-05 12:37 ` David Hildenbrand (Arm)
1 sibling, 1 reply; 7+ messages in thread
From: Anshuman Khandual @ 2026-03-05 5:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Anshuman Khandual, Catalin Marinas, Will Deacon, Ryan Roberts,
David Hildenbrand, Yang Shi, Christoph Lameter, linux-kernel
Linear and vmemmap mappings that get torn down during a memory hot remove
operation might contain leaf level entries on any page table level. If the
requested memory range's linear or vmemmap mappings falls within such leaf
entries, new mappings need to be created for the remaining memory mapped on
the leaf entry earlier, following standard break before make aka BBM rules.
But kernel cannot tolerate BBM and hence remapping to fine grained leaves
would not be possible on systems without BBML2_NOABORT.
Currently memory hot remove operation does not perform such restructuring,
and so removing memory ranges that could split a kernel leaf level mapping
need to be rejected.
While memory_hotplug.c does appear to permit hot removing arbitrary ranges
of memory, the higher layers that drive memory_hotplug (e.g. ACPI, virtio,
...) all appear to treat memory as fixed size devices. So it is impossible
to hot unplug a different amount than was previously hot plugged, and hence
we should never see a rejection in practice, but adding the check makes us
robust against a future change.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Link: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm64/mm/mmu.c | 124 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 118 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f7ccda22d39e..d2a636b712e9 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -2024,6 +2024,111 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
__remove_pgd_mapping(swapper_pg_dir, __phys_to_virt(start), size);
}
+
+static bool addr_splits_kernel_leaf(unsigned long addr)
+{
+ pgd_t *pgdp, pgd;
+ p4d_t *p4dp, p4d;
+ pud_t *pudp, pud;
+ pmd_t *pmdp, pmd;
+ pte_t *ptep, pte;
+
+ /*
+ * If the given address points at a the start address of
+ * a possible leaf, we certainly won't split. Otherwise,
+ * check if we would actually split a leaf by traversing
+ * the page tables further.
+ */
+ if (IS_ALIGNED(addr, PGDIR_SIZE))
+ return false;
+
+ pgdp = pgd_offset_k(addr);
+ pgd = pgdp_get(pgdp);
+ if (!pgd_present(pgd))
+ return false;
+
+ if (IS_ALIGNED(addr, P4D_SIZE))
+ return false;
+
+ p4dp = p4d_offset(pgdp, addr);
+ p4d = p4dp_get(p4dp);
+ if (!p4d_present(p4d))
+ return false;
+
+ if (IS_ALIGNED(addr, PUD_SIZE))
+ return false;
+
+ pudp = pud_offset(p4dp, addr);
+ pud = pudp_get(pudp);
+ if (!pud_present(pud))
+ return false;
+
+ if (pud_leaf(pud))
+ return true;
+
+ if (IS_ALIGNED(addr, CONT_PMD_SIZE))
+ return false;
+
+ pmdp = pmd_offset(pudp, addr);
+ pmd = pmdp_get(pmdp);
+ if (!pmd_present(pmd))
+ return false;
+
+ if (pmd_cont(pmd))
+ return true;
+
+ if (IS_ALIGNED(addr, PMD_SIZE))
+ return false;
+
+ if (pmd_leaf(pmd))
+ return true;
+
+ if (IS_ALIGNED(addr, CONT_PTE_SIZE))
+ return false;
+
+ ptep = pte_offset_kernel(pmdp, addr);
+ pte = __ptep_get(ptep);
+ if (!pte_present(pte))
+ return false;
+
+ if (pte_cont(pte))
+ return true;
+
+ return !IS_ALIGNED(addr, PAGE_SIZE);
+}
+
+static bool can_unmap_without_split(unsigned long pfn, unsigned long nr_pages)
+{
+ unsigned long phys_start, phys_end, start, end;
+
+ phys_start = PFN_PHYS(pfn);
+ phys_end = phys_start + nr_pages * PAGE_SIZE;
+
+ /*
+ * PFN range's linear map edges are leaf entry aligned
+ */
+ start = __phys_to_virt(phys_start);
+ end = __phys_to_virt(phys_end);
+ if (addr_splits_kernel_leaf(start) || addr_splits_kernel_leaf(end)) {
+ pr_warn("[%lx %lx] splits a leaf entry in linear map\n",
+ phys_start, phys_end);
+ return false;
+ }
+
+ /*
+ * PFN range's vmemmap edges are leaf entry aligned
+ */
+ BUILD_BUG_ON(!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP));
+ start = (unsigned long)pfn_to_page(pfn);
+ end = (unsigned long)pfn_to_page(pfn + nr_pages);
+ if (addr_splits_kernel_leaf(start) || addr_splits_kernel_leaf(end)) {
+ pr_warn("[%lx %lx] splits a leaf entry in vmemmap\n",
+ phys_start, phys_end);
+ return false;
+ }
+ return true;
+}
+
/*
* This memory hotplug notifier helps prevent boot memory from being
* inadvertently removed as it blocks pfn range offlining process in
@@ -2032,8 +2137,11 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
* In future if and when boot memory could be removed, this notifier
* should be dropped and free_hotplug_page_range() should handle any
* reserved pages allocated during boot.
+ *
+ * This also blocks any memory remove that would have caused a split
+ * in leaf entry in kernel linear or vmemmap mapping.
*/
-static int prevent_bootmem_remove_notifier(struct notifier_block *nb,
+static int prevent_memory_remove_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct mem_section *ms;
@@ -2079,11 +2187,15 @@ static int prevent_bootmem_remove_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}
}
+
+ if (!can_unmap_without_split(pfn, arg->nr_pages))
+ return NOTIFY_BAD;
+
return NOTIFY_OK;
}
-static struct notifier_block prevent_bootmem_remove_nb = {
- .notifier_call = prevent_bootmem_remove_notifier,
+static struct notifier_block prevent_memory_remove_nb = {
+ .notifier_call = prevent_memory_remove_notifier,
};
/*
@@ -2133,7 +2245,7 @@ static void validate_bootmem_online(void)
}
}
-static int __init prevent_bootmem_remove_init(void)
+static int __init prevent_memory_remove_init(void)
{
int ret = 0;
@@ -2141,13 +2253,13 @@ static int __init prevent_bootmem_remove_init(void)
return ret;
validate_bootmem_online();
- ret = register_memory_notifier(&prevent_bootmem_remove_nb);
+ ret = register_memory_notifier(&prevent_memory_remove_nb);
if (ret)
pr_err("%s: Notifier registration failed %d\n", __func__, ret);
return ret;
}
-early_initcall(prevent_bootmem_remove_init);
+early_initcall(prevent_memory_remove_init);
#endif
pte_t modify_prot_start_ptes(struct vm_area_struct *vma, unsigned long addr,
--
2.30.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping
2026-03-05 5:31 ` [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping Anshuman Khandual
@ 2026-03-05 12:37 ` David Hildenbrand (Arm)
2026-03-05 12:39 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-03-05 12:37 UTC (permalink / raw)
To: Anshuman Khandual, linux-arm-kernel
Cc: Catalin Marinas, Will Deacon, Ryan Roberts, Yang Shi,
Christoph Lameter, linux-kernel
On 3/5/26 06:31, Anshuman Khandual wrote:
> Linear and vmemmap mappings that get torn down during a memory hot remove
> operation might contain leaf level entries on any page table level. If the
> requested memory range's linear or vmemmap mappings falls within such leaf
> entries, new mappings need to be created for the remaining memory mapped on
> the leaf entry earlier, following standard break before make aka BBM rules.
> But kernel cannot tolerate BBM and hence remapping to fine grained leaves
> would not be possible on systems without BBML2_NOABORT.
>
> Currently memory hot remove operation does not perform such restructuring,
> and so removing memory ranges that could split a kernel leaf level mapping
> need to be rejected.
>
> While memory_hotplug.c does appear to permit hot removing arbitrary ranges
> of memory, the higher layers that drive memory_hotplug (e.g. ACPI, virtio,
> ...) all appear to treat memory as fixed size devices. So it is impossible
> to hot unplug a different amount than was previously hot plugged, and hence
> we should never see a rejection in practice, but adding the check makes us
> robust against a future change.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Link: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
> Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
[...]
> +
> + /*
> + * PFN range's linear map edges are leaf entry aligned
> + */
Nit: single-line comments are usually written as
/* ... */
> + start = __phys_to_virt(phys_start);
> + end = __phys_to_virt(phys_end);
> + if (addr_splits_kernel_leaf(start) || addr_splits_kernel_leaf(end)) {
> + pr_warn("[%lx %lx] splits a leaf entry in linear map\n",
> + phys_start, phys_end);
> + return false;
> + }
> +
> + /*
> + * PFN range's vmemmap edges are leaf entry aligned
> + */
Dito.
LGTM, thanks!
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V4 1/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
2026-03-05 5:31 ` [PATCH V4 1/2] " Anshuman Khandual
@ 2026-03-05 12:39 ` David Hildenbrand (Arm)
0 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-03-05 12:39 UTC (permalink / raw)
To: Anshuman Khandual, linux-arm-kernel
Cc: Catalin Marinas, Will Deacon, Ryan Roberts, Yang Shi,
Christoph Lameter, linux-kernel, stable
On 3/5/26 06:31, Anshuman Khandual wrote:
> During a memory hot remove operation, both linear and vmemmap mappings for
> the memory range being removed, get unmapped via unmap_hotplug_range() but
> mapped pages get freed only for vmemmap mapping. This is just a sequential
> operation where each table entry gets cleared, followed by a leaf specific
> TLB flush, and then followed by memory free operation when applicable.
>
> This approach was simple and uniform both for vmemmap and linear mappings.
> But linear mapping might contain CONT marked block memory where it becomes
> necessary to first clear out all entire in the range before a TLB flush.
> This is as per the architecture requirement. Hence batch all TLB flushes
> during the table tear down walk and finally do it in unmap_hotplug_range().
>
> Prior to this fix, it was hypothetically possible for a speculative access
> to a higher address in the contiguous block to fill the TLB with shattered
> entries for the entire contiguous range after a lower address had already
> been cleared and invalidated. Due to the table entries being shattered, the
> subsequent TLB invalidation for the higher address would not then clear the
> TLB entries for the lower address, meaning stale TLB entries could persist.
>
> Besides it also helps in improving the performance via TLBI range operation
> along with reduced synchronization instructions. The time spent executing
> unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
> in KVM guest.
>
> This scheme is not applicable during vmemmap mapping tear down where memory
> needs to be freed and hence a TLB flush is required after clearing out page
> table entry.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
> Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
> Cc: stable@vger.kernel.org
> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/mm/mmu.c | 46 +++++++++++++++++++++++++++++----------------
> 1 file changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index a6a00accf4f9..f7ccda22d39e 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1458,10 +1458,18 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
>
> WARN_ON(!pte_present(pte));
> __pte_clear(&init_mm, addr, ptep);
> - flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
> - if (free_mapped)
> + if (free_mapped) {
> + /*
> + * CONT blocks are not supported in the vmemmap
> + */
Same nit as on patch #2,
/* CONT blocks are not supported in the vmemmap */
Same for the other comments.
Thanks!
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping
2026-03-05 12:37 ` David Hildenbrand (Arm)
@ 2026-03-05 12:39 ` David Hildenbrand (Arm)
2026-03-06 2:46 ` Anshuman Khandual
0 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-03-05 12:39 UTC (permalink / raw)
To: Anshuman Khandual, linux-arm-kernel
Cc: Catalin Marinas, Will Deacon, Ryan Roberts, Yang Shi,
Christoph Lameter, linux-kernel
On 3/5/26 13:37, David Hildenbrand (Arm) wrote:
> On 3/5/26 06:31, Anshuman Khandual wrote:
>> Linear and vmemmap mappings that get torn down during a memory hot remove
>> operation might contain leaf level entries on any page table level. If the
>> requested memory range's linear or vmemmap mappings falls within such leaf
>> entries, new mappings need to be created for the remaining memory mapped on
>> the leaf entry earlier, following standard break before make aka BBM rules.
>> But kernel cannot tolerate BBM and hence remapping to fine grained leaves
>> would not be possible on systems without BBML2_NOABORT.
>>
>> Currently memory hot remove operation does not perform such restructuring,
>> and so removing memory ranges that could split a kernel leaf level mapping
>> need to be rejected.
>>
>> While memory_hotplug.c does appear to permit hot removing arbitrary ranges
>> of memory, the higher layers that drive memory_hotplug (e.g. ACPI, virtio,
>> ...) all appear to treat memory as fixed size devices. So it is impossible
>> to hot unplug a different amount than was previously hot plugged, and hence
>> we should never see a rejection in practice, but adding the check makes us
>> robust against a future change.
>>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will@kernel.org>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-kernel@vger.kernel.org
>> Link: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
>> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
>> Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>
> [...]
>
>> +
>> + /*
>> + * PFN range's linear map edges are leaf entry aligned
>> + */
>
> Nit: single-line comments are usually written as
>
> /* ... */
>
>> + start = __phys_to_virt(phys_start);
>> + end = __phys_to_virt(phys_end);
>> + if (addr_splits_kernel_leaf(start) || addr_splits_kernel_leaf(end)) {
>> + pr_warn("[%lx %lx] splits a leaf entry in linear map\n",
>> + phys_start, phys_end);
>> + return false;
>> + }
>> +
>> + /*
>> + * PFN range's vmemmap edges are leaf entry aligned
>> + */
>
> Dito.
>
> LGTM, thanks!
>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
>
In fact,
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
:)
--
Cheers,
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping
2026-03-05 12:39 ` David Hildenbrand (Arm)
@ 2026-03-06 2:46 ` Anshuman Khandual
0 siblings, 0 replies; 7+ messages in thread
From: Anshuman Khandual @ 2026-03-06 2:46 UTC (permalink / raw)
To: David Hildenbrand (Arm), linux-arm-kernel
Cc: Catalin Marinas, Will Deacon, Ryan Roberts, Yang Shi,
Christoph Lameter, linux-kernel
On 05/03/26 6:09 PM, David Hildenbrand (Arm) wrote:
> On 3/5/26 13:37, David Hildenbrand (Arm) wrote:
>> On 3/5/26 06:31, Anshuman Khandual wrote:
>>> Linear and vmemmap mappings that get torn down during a memory hot remove
>>> operation might contain leaf level entries on any page table level. If the
>>> requested memory range's linear or vmemmap mappings falls within such leaf
>>> entries, new mappings need to be created for the remaining memory mapped on
>>> the leaf entry earlier, following standard break before make aka BBM rules.
>>> But kernel cannot tolerate BBM and hence remapping to fine grained leaves
>>> would not be possible on systems without BBML2_NOABORT.
>>>
>>> Currently memory hot remove operation does not perform such restructuring,
>>> and so removing memory ranges that could split a kernel leaf level mapping
>>> need to be rejected.
>>>
>>> While memory_hotplug.c does appear to permit hot removing arbitrary ranges
>>> of memory, the higher layers that drive memory_hotplug (e.g. ACPI, virtio,
>>> ...) all appear to treat memory as fixed size devices. So it is impossible
>>> to hot unplug a different amount than was previously hot plugged, and hence
>>> we should never see a rejection in practice, but adding the check makes us
>>> robust against a future change.
>>>
>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>>> Cc: Will Deacon <will@kernel.org>
>>> Cc: linux-arm-kernel@lists.infradead.org
>>> Cc: linux-kernel@vger.kernel.org
>>> Link: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
>>> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
>>> Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>>> ---
>>
>> [...]
>>
>>> +
>>> + /*
>>> + * PFN range's linear map edges are leaf entry aligned
>>> + */
>>
>> Nit: single-line comments are usually written as
>>
>> /* ... */
>>
>>> + start = __phys_to_virt(phys_start);
>>> + end = __phys_to_virt(phys_end);
>>> + if (addr_splits_kernel_leaf(start) || addr_splits_kernel_leaf(end)) {
>>> + pr_warn("[%lx %lx] splits a leaf entry in linear map\n",
>>> + phys_start, phys_end);
>>> + return false;
>>> + }
>>> +
>>> + /*
>>> + * PFN range's vmemmap edges are leaf entry aligned
>>> + */
>>
>> Dito.
>>
>> LGTM, thanks!
>>
>> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
>>
>
> In fact,
>
> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
>
> :)
>
Thanks for the review. Sure, will respin with the comment fixes next week.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-03-06 2:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 5:31 [PATCH V4 0/2] arm64/mm: Enable batched TLB flush in unmap_hotplug_range() Anshuman Khandual
2026-03-05 5:31 ` [PATCH V4 1/2] " Anshuman Khandual
2026-03-05 12:39 ` David Hildenbrand (Arm)
2026-03-05 5:31 ` [PATCH V4 2/2] arm64/mm: Reject memory removal that splits a kernel leaf mapping Anshuman Khandual
2026-03-05 12:37 ` David Hildenbrand (Arm)
2026-03-05 12:39 ` David Hildenbrand (Arm)
2026-03-06 2:46 ` Anshuman Khandual
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox