* [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis
@ 2026-02-19 2:03 Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 1/4] x86/mm/pat: Convert pte code to use " Vishal Moola (Oracle)
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Vishal Moola (Oracle) @ 2026-02-19 2:03 UTC (permalink / raw)
To: linux-kernel, linux-mm, x86, Mike Rapoport (Microsoft), Dave Hansen
Cc: Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra, Vishal Moola (Oracle)
set_memory.c has a call to pagetable_free(), while the allocation sites
use get_free_pages(). This causes issues separately allocating ptdescs
from struct page.
It turns out that we can just use the appropriate generic pagetable
apis for allocation/freeing. This helps simplify and standardize the
code.
In the short term, this helps enable Matthew's work to allocate frozen
pagetables[1]. And in the long term, this will help us cleanly split
ptdesc allocations from struct page[2].
[1] https://lore.kernel.org/linux-mm/20251113140448.1814860-1-willy@infradead.org/
[2] https://lore.kernel.org/linux-mm/20251020001652.2116669-1-willy@infradead.org/
------
Based on current mm-new.
v6:
- Drop the renaming of *page* functions
- Use existing page table api instead of creating new apis
- Split the pmd and populate_pgd() changes into separate patches
- Reword the cover letter to describe the new approach
v5 link:
https://lore.kernel.org/all/20260211195233.368497-1-vishal.moola@gmail.com/
Vishal Moola (Oracle) (4):
x86/mm/pat: Convert pte code to use page table apis
x86/mm/pat: Convert pmd code to use page table apis
x86/mm/pat: Convert populate_pgd() to use page table apis
x86/mm/pat: Convert split_large_page() to use ptdescs
arch/x86/mm/pat/set_memory.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 1/4] x86/mm/pat: Convert pte code to use page table apis
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
@ 2026-02-19 2:03 ` Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 2/4] x86/mm/pat: Convert pmd " Vishal Moola (Oracle)
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Vishal Moola (Oracle) @ 2026-02-19 2:03 UTC (permalink / raw)
To: linux-kernel, linux-mm, x86, Mike Rapoport (Microsoft), Dave Hansen
Cc: Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra, Vishal Moola (Oracle)
We need all allocation and free sites to use the ptdesc APIs in order to
allocate them separately from regular pages. Convert the pte
allocation/free sites to use the generic page table apis, since those
use ptdescs already.
Pass through init_mm since these are kernel page tables,
pte_alloc_one_kernel() effectively becomes a no-op otherwise.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
arch/x86/mm/pat/set_memory.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 6c6eb486f7a6..d52010fd3023 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1408,7 +1408,7 @@ static bool try_to_free_pte_page(pte_t *pte)
if (!pte_none(pte[i]))
return false;
- free_page((unsigned long)pte);
+ pte_free_kernel(&init_mm, pte);
return true;
}
@@ -1539,7 +1539,7 @@ static void unmap_pud_range(p4d_t *p4d, unsigned long start, unsigned long end)
static int alloc_pte_page(pmd_t *pmd)
{
- pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL);
+ pte_t *pte = pte_alloc_one_kernel(&init_mm);
if (!pte)
return -1;
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 2/4] x86/mm/pat: Convert pmd code to use page table apis
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 1/4] x86/mm/pat: Convert pte code to use " Vishal Moola (Oracle)
@ 2026-02-19 2:03 ` Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 3/4] x86/mm/pat: Convert populate_pgd() " Vishal Moola (Oracle)
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Vishal Moola (Oracle) @ 2026-02-19 2:03 UTC (permalink / raw)
To: linux-kernel, linux-mm, x86, Mike Rapoport (Microsoft), Dave Hansen
Cc: Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra, Vishal Moola (Oracle)
We need all allocation and free sites to use the ptdesc APIs in order to
allocate them separately from regular pages. Convert the pmd
allocation/free sites to use the generic page table apis, since those
use ptdescs already.
Pass through init_mm since these are kernel page tables, pmd_alloc_one()
needs it to identify kernel page tables. Also, the generic implementation
doesn't use the second argument. Pass it a placeholder so we don't have
to reimplement it or risk breaking other architectures.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
arch/x86/mm/pat/set_memory.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index d52010fd3023..655bef618ea0 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1420,7 +1420,7 @@ static bool try_to_free_pmd_page(pmd_t *pmd)
if (!pmd_none(pmd[i]))
return false;
- free_page((unsigned long)pmd);
+ pmd_free(&init_mm, pmd);
return true;
}
@@ -1549,7 +1549,10 @@ static int alloc_pte_page(pmd_t *pmd)
static int alloc_pmd_page(pud_t *pud)
{
- pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL);
+ /* The generic implementation of pmd_alloc_one() doesn't use
+ * the second argument. Pass it 0 as a placeholder.
+ */
+ pmd_t *pmd = pmd_alloc_one(&init_mm, 0);
if (!pmd)
return -1;
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 3/4] x86/mm/pat: Convert populate_pgd() to use page table apis
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 1/4] x86/mm/pat: Convert pte code to use " Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 2/4] x86/mm/pat: Convert pmd " Vishal Moola (Oracle)
@ 2026-02-19 2:03 ` Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 4/4] x86/mm/pat: Convert split_large_page() to use ptdescs Vishal Moola (Oracle)
2026-02-20 10:25 ` [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Mike Rapoport
4 siblings, 0 replies; 6+ messages in thread
From: Vishal Moola (Oracle) @ 2026-02-19 2:03 UTC (permalink / raw)
To: linux-kernel, linux-mm, x86, Mike Rapoport (Microsoft), Dave Hansen
Cc: Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra, Vishal Moola (Oracle)
We need all allocation and free sites to use the ptdesc APIs in order to
allocate them separately from regular pages. Convert the remaining
get_zeroed_page() calls to the generic page table apis, since those
use ptdescs already.
Pass through init_mm since these are kernel page tables, both functions
need it to identify kernel page tables. Also, the generic
implementations don't use the second argument. Pass it a placeholder so
we don't have to reimplement it or risk breaking other architectures.
Its not obvious if these pages get freed. Regardless, the only other
possible free paths have already been converted, and my frozen page
table test kernel hasn't found any issues.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
arch/x86/mm/pat/set_memory.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 655bef618ea0..8f74d4bfd591 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1746,7 +1746,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
pgd_entry = cpa->pgd + pgd_index(addr);
if (pgd_none(*pgd_entry)) {
- p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL);
+ /* The generic implementation of p4d_alloc_one()
+ * doesn't use the second argument. Pass it 0 as
+ * a placeholder.
+ */
+ p4d = p4d_alloc_one(&init_mm, 0);
if (!p4d)
return -1;
@@ -1758,7 +1762,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
*/
p4d = p4d_offset(pgd_entry, addr);
if (p4d_none(*p4d)) {
- pud = (pud_t *)get_zeroed_page(GFP_KERNEL);
+ /* The generic implementation of pud_alloc_one()
+ * doesn't use the second argument. Pass it 0 as
+ * a placeholder.
+ */
+ pud = pud_alloc_one(&init_mm, 0);
if (!pud)
return -1;
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 4/4] x86/mm/pat: Convert split_large_page() to use ptdescs
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
` (2 preceding siblings ...)
2026-02-19 2:03 ` [PATCH v6 3/4] x86/mm/pat: Convert populate_pgd() " Vishal Moola (Oracle)
@ 2026-02-19 2:03 ` Vishal Moola (Oracle)
2026-02-20 10:25 ` [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Mike Rapoport
4 siblings, 0 replies; 6+ messages in thread
From: Vishal Moola (Oracle) @ 2026-02-19 2:03 UTC (permalink / raw)
To: linux-kernel, linux-mm, x86, Mike Rapoport (Microsoft), Dave Hansen
Cc: Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra, Vishal Moola (Oracle)
In order to separately allocate ptdescs from pages, we need all allocation
and free sites to use the appropriate functions.
split_large_page() allocates a page to be used as a page table. This
should be allocating a ptdesc, so convert it.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/x86/mm/pat/set_memory.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 8f74d4bfd591..e26535f3b8bd 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1119,9 +1119,10 @@ static void split_set_pte(struct cpa_data *cpa, pte_t *pte, unsigned long pfn,
static int
__split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
- struct page *base)
+ struct ptdesc *ptdesc)
{
unsigned long lpaddr, lpinc, ref_pfn, pfn, pfninc = 1;
+ struct page *base = ptdesc_page(ptdesc);
pte_t *pbase = (pte_t *)page_address(base);
unsigned int i, level;
pgprot_t ref_prot;
@@ -1226,18 +1227,18 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
unsigned long address)
{
- struct page *base;
+ struct ptdesc *ptdesc;
if (!debug_pagealloc_enabled())
spin_unlock(&cpa_lock);
- base = alloc_pages(GFP_KERNEL, 0);
+ ptdesc = pagetable_alloc(GFP_KERNEL, 0);
if (!debug_pagealloc_enabled())
spin_lock(&cpa_lock);
- if (!base)
+ if (!ptdesc)
return -ENOMEM;
- if (__split_large_page(cpa, kpte, address, base))
- __free_page(base);
+ if (__split_large_page(cpa, kpte, address, ptdesc))
+ pagetable_free(ptdesc);
return 0;
}
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
` (3 preceding siblings ...)
2026-02-19 2:03 ` [PATCH v6 4/4] x86/mm/pat: Convert split_large_page() to use ptdescs Vishal Moola (Oracle)
@ 2026-02-20 10:25 ` Mike Rapoport
4 siblings, 0 replies; 6+ messages in thread
From: Mike Rapoport @ 2026-02-20 10:25 UTC (permalink / raw)
To: Vishal Moola (Oracle)
Cc: linux-kernel, linux-mm, x86, Dave Hansen, Matthew Wilcox (Oracle),
akpm, Andy Lutomirski, Peter Zijlstra
On Wed, Feb 18, 2026 at 06:03:50PM -0800, Vishal Moola (Oracle) wrote:
> set_memory.c has a call to pagetable_free(), while the allocation sites
> use get_free_pages(). This causes issues separately allocating ptdescs
> from struct page.
>
> It turns out that we can just use the appropriate generic pagetable
> apis for allocation/freeing. This helps simplify and standardize the
> code.
>
> In the short term, this helps enable Matthew's work to allocate frozen
> pagetables[1]. And in the long term, this will help us cleanly split
> ptdesc allocations from struct page[2].
>
> [1] https://lore.kernel.org/linux-mm/20251113140448.1814860-1-willy@infradead.org/
> [2] https://lore.kernel.org/linux-mm/20251020001652.2116669-1-willy@infradead.org/
>
> ------
>
> Based on current mm-new.
>
> v6:
> - Drop the renaming of *page* functions
> - Use existing page table api instead of creating new apis
> - Split the pmd and populate_pgd() changes into separate patches
> - Reword the cover letter to describe the new approach
>
> v5 link:
> https://lore.kernel.org/all/20260211195233.368497-1-vishal.moola@gmail.com/
>
> Vishal Moola (Oracle) (4):
> x86/mm/pat: Convert pte code to use page table apis
> x86/mm/pat: Convert pmd code to use page table apis
> x86/mm/pat: Convert populate_pgd() to use page table apis
> x86/mm/pat: Convert split_large_page() to use ptdescs
>
> arch/x86/mm/pat/set_memory.c | 36 ++++++++++++++++++++++++------------
> 1 file changed, 24 insertions(+), 12 deletions(-)
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
>
> --
> 2.53.0
>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-20 10:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-19 2:03 [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 1/4] x86/mm/pat: Convert pte code to use " Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 2/4] x86/mm/pat: Convert pmd " Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 3/4] x86/mm/pat: Convert populate_pgd() " Vishal Moola (Oracle)
2026-02-19 2:03 ` [PATCH v6 4/4] x86/mm/pat: Convert split_large_page() to use ptdescs Vishal Moola (Oracle)
2026-02-20 10:25 ` [PATCH v6 0/4] Convert x86/mm/pat to generic page table apis Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox