All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Vishal Moola <vishal.moola@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
	 Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	 Thomas Gleixner <tglx@kernel.org>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	 x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	 "Mike Rapoport (Microsoft)" <rppt@kernel.org>,
	Jason Gunthorpe <jgg@ziepe.ca>,
	 Lu Baolu <baolu.lu@linux.intel.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	 David Hildenbrand <david@kernel.org>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	 Kiryl Shutsemau <kas@kernel.org>,
	iommu@lists.linux.dev, Kevin Tian <kevin.tian@intel.com>,
	 stable@vger.kernel.org
Subject: Re: [PATCH] x86/mm/pat: allocate split page tables as kernel page tables
Date: Tue, 21 Jul 2026 08:43:51 +0100	[thread overview]
Message-ID: <al8hE_ded6qyWiDv@lucifer> (raw)
In-Reply-To: <al5_Le9QlD4zlt25@fedora>

On Mon, Jul 20, 2026 at 01:03:57PM -0700, Vishal Moola wrote:
> On Mon, Jul 20, 2026 at 01:01:00PM -0700, Vishal Moola wrote:
> > On Mon, Jul 20, 2026 at 10:27:29AM +0100, Lorenzo Stoakes (ARM) wrote:
> > > When splitting a large page in CPA in __split_large_page() we allocate a
> > > PTE directly without going through the standard page table allocation
> > > routines such as pte_alloc_one_kernel().
> > >
> > > This means the page table constructor is never called nor is the page table
> > > marked as a kernel page table.
> > >
> > > The former results in the folio associated with the page table not being
> > > marked as a page table (__pagetable_ctor() is never called thus neither is
> > > __folio_set_pgtable()) nor are statistics updated to reflect
> > > it (lruvec_stat_add_folio() is never called).
> > >
> > > The latter issue of failing to mark the page table as a kernel page
> > > table (ptdesc_set_kernel() is never called) is far more problematic.
> > >
> > > Since commit 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page
> > > tables") kernel page table freeing has been batched and since the
> > > subsequent commit e37d5a2d60a3 ("iommu/sva: invalidate stale IOTLB entries
> > > for kernel address space") IOTLB cache entries for kernel page tables have
> > > been invalidated upon being freed.
> > >
> > > Since split page tables are freed without this invalidation, the IOTLB can
> > > contain stale entries for them.
> > >
> > > Resolve the issue by using the ordinary PTE allocation API at split time.
> > >
> > > This results in these kernel page tables invoking a page table constructor,
> > > and thus requires a page table destructor.
> > >
> > > Since we cannot assume one is always present (early allocated direct map
> > > page tables are not marked as such), we conditionally call
> > > pagetable_dtor_free() if the PG_table folio flag for the ptdesc is set,
> > > otherwise we free the page table via pagetable_free().
> > >
> > > Regardless of which path is taken page tables marked as kernel page tables,
> > > which now includes split page tables, take the correct route through
> > > pagetable_free_kernel().
> > >
> > > There is a user-visible side effect in that split page tables will appear
> > > in nr_page_table_pages in /proc/vmstat (as do other kernel page tables
> > > allocated after early boot), however this is a positive change.
> > >
> > > This issue started being markedly problematic after commit
> > > 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") so
> > > choose this as the Fixes target.
> > >
> > > Fixes: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> > > ---
> > >  arch/x86/mm/pat/set_memory.c | 21 ++++++++++++---------
> > >  1 file changed, 12 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > > index 301fb9e77d91..a67ca33b9dd1 100644
> > > --- a/arch/x86/mm/pat/set_memory.c
> > > +++ b/arch/x86/mm/pat/set_memory.c
> > > @@ -439,7 +439,11 @@ static void __cpa_collapse_large_pages(struct cpa_data *cpa)
> > >
> > >  	list_for_each_entry_safe(ptdesc, tmp, &pgtables, pt_list) {
> > >  		list_del(&ptdesc->pt_list);
> > > -		pagetable_free(ptdesc);
> > > +
> > > +		if (folio_test_pgtable(ptdesc_folio(ptdesc)))
> > > +			pagetable_dtor_free(ptdesc);
> > > +		else
> > > +			pagetable_free(ptdesc);
> >
> > Lets not introduce more folio-ptdesc crossovers, we're trying to get
> > rid of them :)
> >
> > I believe pagetable_dtor_free() should do what you're looking for on its
> > own anyway.
>
> Actually, looking at it closer, maybe not because of the conditional
> portion? But that makes me think it might be better to just replace the
> ptdesc_clear_kernel() with pagetable_dtor() in the free function...

Well some kernel page tables are still allocated without ctor (early allocated
direct map for isntance), and if you did pagetable_dtor_free() it
unconditionally calls pagetable_dtor().

The ptlock_free() and __folio_clear_pgtable() there would be harmelss (no locks
assigned for kernel page table, and if PG_table never set clearing it is a noop)
but the lruvec_stat_sub_folio() would cause an unbalanced decrement of
nr_page_table_pages.

It sucks, but until everything is updated to call the ctor we have to do it this
way :>)

Cheers, Lorenzo

  reply	other threads:[~2026-07-21  7:44 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20  9:27 [PATCH] x86/mm/pat: allocate split page tables as kernel page tables Lorenzo Stoakes (ARM)
2026-07-20 20:01 ` Vishal Moola
2026-07-20 20:03   ` Vishal Moola
2026-07-21  7:43     ` Lorenzo Stoakes (ARM) [this message]
2026-07-21  9:45       ` Vishal Moola
2026-07-21  9:58         ` Lorenzo Stoakes (ARM)
2026-07-21 10:32           ` Mike Rapoport
2026-07-21 12:00             ` Lorenzo Stoakes (ARM)
2026-07-21 12:09               ` Lorenzo Stoakes (ARM)
2026-07-21 13:51                 ` Mike Rapoport
2026-07-21 17:06                   ` Vishal Moola
2026-07-20 23:17 ` Andrew Morton

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=al8hE_ded6qyWiDv@lucifer \
    --to=ljs@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=baolu.lu@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@kernel.org \
    --cc=hpa@zytor.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=kas@kernel.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rppt@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@kernel.org \
    --cc=vishal.moola@gmail.com \
    --cc=x86@kernel.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.