Re: [PATCH v3 10/26] mm: Add more flags for __apply_to_page_range()
From: Brendan Jackman
Date: Thu Aug 13 2026 - 12:41:54 EST
On Tue Aug 4, 2026 at 1:08 AM BST, Yosry Ahmed wrote:
> On Sun, Jul 26, 2026 at 10:22:43PM +0000, Brendan Jackman wrote:
>> Add two flags to make this API more generic:
>>
>> 1. Separate "create" into two levels - one to allow creating new
>> mappings without allocating pagetables, and one for the current
>> behaviour that allows both of these.
>>
>> 2. Create a new flag to report that the caller has taken care of
>> synchronization and no locks are required.
>>
>> Both of these will serve to allow calling this API from restricted
>> contexts where allocation and pagetable locking are not possible.
>>
>> Signed-off-by: Brendan Jackman <jackmanb@xxxxxxxxxx>
>> ---
>> mm/internal.h | 26 +++++++++++++++++++++++++-
>> mm/memory.c | 59 ++++++++++++++++++++++++++++++++++-------------------------
>> 2 files changed, 59 insertions(+), 26 deletions(-)
>>
>> diff --git a/mm/internal.h b/mm/internal.h
>> index 395331a12d62d..5a237d9c5fa96 100644
>> --- a/mm/internal.h
>> +++ b/mm/internal.h
>> @@ -1662,9 +1662,33 @@ static inline bool can_spin_trylock(void)
>>
>> /*
>> * Create a mapping if it doesn't exist. (Otherwise, skip regions with no
>> - * existing mapping, and return an error for regions with no leaf pagetable).
>> + * existing mapping). This doesn't allow allocating, most users will want
>> + * PGRANGE_ALLOC.
>> + *
>> + * Do not test this bit directly as it is implied by PGRANGE_ALLOC, use
>> + * pgrange_create() instead.
>> */
>> #define PGRANGE_CREATE (1 << 0)
>> +/*
>> + * Allocate a pagetable if one is missing. (Otherwise, return an error for
>> + * regions with no leaf pagetable). Also implies PGRANGE_CREATE.
>> + *
>> + * Note that __apply_to_page_range() assumes that pagetables for the area are
>> + * already initialised down to PMD level, so this only affects PTEs in practice.
>> + */
>> +#define PGRANGE_ALLOC (1 << 1)
>> +/*
>> + * Do not take any locks. This means the caller has taken care of
>> + * synchronisation. This is incompatible with PGRANGE_ALLOC and also with
>> + * mm=&init_mm.
>> + */
>> +#define PGRANGE_NOLOCK (1 << 2)
>
> I assume this is used by the mermap as locking is not required because
> the mappings are per-CPU and migration is disabled while the mermap is
> used?
Exactly.
> Also, why is this incompatible with init_mm? It actually seems like
> apply_to_pte_range() is always lockless for init_mm (uses
> pte_offset_kernel()), probably callers are also synchronizing in their
> own way (e.g. exclusive access to a vmap area?).
Hm. My initial reaction was that there was code like this somewhere:
if (mm == &init_mm)
spin_lock(&pgd_lock);
But I can't find it in these paths and neither can Fable. So yeah I
think this bit about init_mm can just be dropped.