From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9929246783 for ; Tue, 4 Aug 2026 00:08:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785802120; cv=none; b=VAcL6/h+yakgY4BG3ZBs1EPqbbYZFMUMWyfh+wJREHAAaO3oIBur9xqVAMtSeCdg87smzBciGWc0eHx0fbgPWLH5SLS6675/15wkAMq190d+KJVyPeHq4wt0PMK1qaMGjq9quThZlRhdeJMcSvzNRnSvugrfB5bMDJFwEtJzxvg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785802120; c=relaxed/simple; bh=uiBAWm+6CwQDXYGjnjg5rLZmJqjm+PJtlzMvPB7A88M=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=qfhCoMK0knZvVya9kprtb+jyrxjSA0EHlgHqlM8Mf+U/u5yzzCMjRPAoPlni99nXUSVmFAtiG138HfcxoT3/UJ/rRucENe3nzi1qsIUi/tmSw4Tt5scMJ9Ly7hEazKslzhdEaoHbgcdSBfhtUn43O/L5e7MB/3iOobZrqOU+zs4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=INrp9BoK; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="INrp9BoK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71D501F000E9; Tue, 4 Aug 2026 00:08:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785802119; bh=UEVPjOd239FULOvZJt9FR49Oi4ffilzOlCFErD9Rzjg=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=INrp9BoKCaDD3HljHkktfuaw0iKD8M8iLP8gQ+THjIJjQxWsXpwGwmFSSHjBm2FiG uPPiqgNn6v9t+CORTpzeQ+g7qSaga65SX4V+WvuraWbYXyS5QR9Xu/zGXhmNLIEFpS 7LWyLkeFd+dPKLYC8XbZrxZH2xrjrcPiEtGqp8EXLP8pGOfyvRz/+V7/HWvHBYOLQF kKKW8X6xq9+QDLJY/JyUV9Fxdv3HIMmjMurIk64DZ0KtEUXGkKQCCh9vD/cWQ95IMh PRRcZvkVIxeXcZ2xYnvV4YqvNjtG16xoDO3rqoHsNU25hNm8opUirunagcJ3jTu4pk v0mGX89YWJC3Q== Date: Tue, 4 Aug 2026 00:08:37 +0000 From: Yosry Ahmed To: Brendan Jackman Cc: Borislav Petkov , Dave Hansen , Peter Zijlstra , Andrew Morton , David Hildenbrand , Vlastimil Babka , Mike Rapoport , Wei Xu , Johannes Weiner , Zi Yan , Lorenzo Stoakes , linux-mm@kvack.org, linux-kernel@vger.kernel.org, x86@kernel.org, Sumit Garg , Will Deacon , rientjes@google.com, "Kalyazin, Nikita" , patrick.roy@linux.dev, "Itazuri, Takahiro" , Andy Lutomirski , David Kaplan , Thomas Gleixner , Patrick Bellasi , Reiji Watanabe , Sean Christopherson Subject: Re: [PATCH v3 10/26] mm: Add more flags for __apply_to_page_range() Message-ID: References: <20260726-page_alloc-unmapped-v3-0-6f5729aa9832@google.com> <20260726-page_alloc-unmapped-v3-10-6f5729aa9832@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260726-page_alloc-unmapped-v3-10-6f5729aa9832@google.com> 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 > --- > 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? 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?). > + > + > +static inline bool pgrange_create(unsigned int flags) > +{ > + return flags & (PGRANGE_CREATE | PGRANGE_ALLOC); > +} > > int __apply_to_page_range(struct mm_struct *mm, unsigned long addr, > unsigned long size, pte_fn_t fn, > diff --git a/mm/memory.c b/mm/memory.c > index c4defefea1574..d00508db1021e 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -3441,30 +3441,35 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, > pte_fn_t fn, void *data, unsigned int flags, > pgtbl_mod_mask *mask) > { > - bool create = flags & PGRANGE_CREATE; > pte_t *pte, *mapped_pte; > int err = 0; > spinlock_t *ptl; > > - if (create) { > + if (flags & PGRANGE_ALLOC) { > + VM_WARN_ON(flags & PGRANGE_NOLOCK); > + > mapped_pte = pte = (mm == &init_mm) ? > pte_alloc_kernel_track(pmd, addr, mask) : > pte_alloc_map_lock(mm, pmd, addr, &ptl); > if (!pte) > return -ENOMEM; > } else { > - mapped_pte = pte = (mm == &init_mm) ? > - pte_offset_kernel(pmd, addr) : > - pte_offset_map_lock(mm, pmd, addr, &ptl); > + if (mm == &init_mm) > + pte = pte_offset_kernel(pmd, addr); > + else if (flags & PGRANGE_NOLOCK) > + pte = pte_offset_map(pmd, addr); > + else > + pte = pte_offset_map_lock(mm, pmd, addr, &ptl); > if (!pte) > return -EINVAL; > + mapped_pte = pte; > } > > lazy_mmu_mode_enable(); > > if (fn) { > do { > - if (create || !pte_none(ptep_get(pte))) { > + if (pgrange_create(flags) || !pte_none(ptep_get(pte))) { > err = fn(pte, addr, data); > if (err) > break; > @@ -3475,8 +3480,13 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, > > lazy_mmu_mode_disable(); > > - if (mm != &init_mm) > - pte_unmap_unlock(mapped_pte, ptl); > + if (mm != &init_mm) { > + if (flags & PGRANGE_NOLOCK) > + pte_unmap(mapped_pte); > + else > + pte_unmap_unlock(mapped_pte, ptl); > + } > + > return err; > } [..]