From: Ryan Roberts <ryan.roberts@arm.com>
To: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
Dev Jain <dev.jain@arm.com>
Cc: akpm@linux-foundation.org, david@redhat.com, willy@infradead.org,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
catalin.marinas@arm.com, will@kernel.org,
Liam.Howlett@oracle.com, vbabka@suse.cz, jannh@google.com,
anshuman.khandual@arm.com, peterx@redhat.com, joey.gouly@arm.com,
ioworker0@gmail.com, baohua@kernel.org, kevin.brodsky@arm.com,
quic_zhenhuah@quicinc.com, christophe.leroy@csgroup.eu,
yangyicong@hisilicon.com, linux-arm-kernel@lists.infradead.org,
hughd@google.com, yang@os.amperecomputing.com, ziy@nvidia.com
Subject: Re: [PATCH v4 1/4] mm: Optimize mprotect() for MM_CP_PROT_NUMA by batch-skipping PTEs
Date: Mon, 30 Jun 2025 12:39:33 +0100 [thread overview]
Message-ID: <3df4db71-752f-4c59-841b-84025914870d@arm.com> (raw)
In-Reply-To: <79a48c48-53b1-4002-a8b2-447e69d96e49@lucifer.local>
On 30/06/2025 12:25, Lorenzo Stoakes wrote:
> On Sat, Jun 28, 2025 at 05:04:32PM +0530, Dev Jain wrote:
>> In case of prot_numa, there are various cases in which we can skip to the
>> next iteration. Since the skip condition is based on the folio and not
>> the PTEs, we can skip a PTE batch. Additionally refactor all of this
>> into a new function to clean up the existing code.
>
> Hmm, is this a completely new concept for this series?
>
> Please try not to introduce brand new things to a series midway through.
>
> This seems to be adding a whole ton of questionable logic for an edge case.
>
> Can we maybe just drop this for this series please?
From my perspective, at least, there are no new logical changes in here vs the
previous version. And I don't think the patches have been re-organised either.
David (I think?) was asking for the name of the patch to be changed to include
MM_CP_PROT_NUMA and also for the code to be moved out of line to it's own
function. That's all that Dev has done AFAICT (although as per my review
comments, the refactoring has introduced a bug).
My preference is that we should ultimately support this batching. It could be a
separate series if you insist, but it's all contbuting to the same goal
ultimately; making mprotect support PTE batching.
Just my 2c.
Thanks,
Ryan
>
>>
>> Signed-off-by: Dev Jain <dev.jain@arm.com>
>> ---
>> mm/mprotect.c | 134 ++++++++++++++++++++++++++++++++------------------
>> 1 file changed, 87 insertions(+), 47 deletions(-)
>>
>> diff --git a/mm/mprotect.c b/mm/mprotect.c
>> index 88709c01177b..af10a7fbe6b8 100644
>> --- a/mm/mprotect.c
>> +++ b/mm/mprotect.c
>> @@ -83,6 +83,83 @@ bool can_change_pte_writable(struct vm_area_struct *vma, unsigned long addr,
>> return pte_dirty(pte);
>> }
>>
>> +static int mprotect_folio_pte_batch(struct folio *folio, unsigned long addr,
>> + pte_t *ptep, pte_t pte, int max_nr_ptes)
>> +{
>> + const fpb_t flags = FPB_IGNORE_DIRTY | FPB_IGNORE_SOFT_DIRTY;
>> +
>> + if (!folio || !folio_test_large(folio) || (max_nr_ptes == 1))
>> + return 1;
>> +
>> + return folio_pte_batch(folio, addr, ptep, pte, max_nr_ptes, flags,
>> + NULL, NULL, NULL);
>> +}
>
> I find it really odd that you're introducing this in a seemingly unrelated change.
>
> Also won't this conflict with David's changes?
>
> I know you like to rush out a dozen series at once, but once again I'm asking
> maybe please hold off?
>
> I seem to remember David asked you for the same thing because of this, but maybe
> I'm misremembering.
>
> We have only so much review resource and adding in brand new concepts mid-way
> and doing things that blatantly conflict with other series really doesn't help.
>
>> +
>> +static int prot_numa_skip_ptes(struct folio **foliop, struct vm_area_struct *vma,
>> + unsigned long addr, pte_t oldpte, pte_t *pte, int target_node,
>> + int max_nr_ptes)
>> +{
>> + struct folio *folio = NULL;
>> + int nr_ptes = 1;
>> + bool toptier;
>> + int nid;
>> +
>> + /* Avoid TLB flush if possible */
>> + if (pte_protnone(oldpte))
>> + goto skip_batch;
>> +
>> + folio = vm_normal_folio(vma, addr, oldpte);
>> + if (!folio)
>> + goto skip_batch;
>> +
>> + if (folio_is_zone_device(folio) || folio_test_ksm(folio))
>> + goto skip_batch;
>> +
>> + /* Also skip shared copy-on-write pages */
>> + if (is_cow_mapping(vma->vm_flags) &&
>> + (folio_maybe_dma_pinned(folio) || folio_maybe_mapped_shared(folio)))
>> + goto skip_batch;
>> +
>> + /*
>> + * While migration can move some dirty pages,
>> + * it cannot move them all from MIGRATE_ASYNC
>> + * context.
>> + */
>> + if (folio_is_file_lru(folio) && folio_test_dirty(folio))
>> + goto skip_batch;
>> +
>> + /*
>> + * Don't mess with PTEs if page is already on the node
>> + * a single-threaded process is running on.
>> + */
>> + nid = folio_nid(folio);
>> + if (target_node == nid)
>> + goto skip_batch;
>> +
>> + toptier = node_is_toptier(nid);
>> +
>> + /*
>> + * Skip scanning top tier node if normal numa
>> + * balancing is disabled
>> + */
>> + if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_NORMAL) && toptier)
>> + goto skip_batch;
>> +
>> + if (folio_use_access_time(folio)) {
>> + folio_xchg_access_time(folio, jiffies_to_msecs(jiffies));
>> +
>> + /* Do not skip in this case */
>> + nr_ptes = 0;
>> + goto out;
>> + }
>> +
>> +skip_batch:
>> + nr_ptes = mprotect_folio_pte_batch(folio, addr, pte, oldpte, max_nr_ptes);
>> +out:
>> + *foliop = folio;
>> + return nr_ptes;
>> +}
>
> Yeah yuck. I don't like that we're doing all this for this edge case.
>
>> +
>> static long change_pte_range(struct mmu_gather *tlb,
>> struct vm_area_struct *vma, pmd_t *pmd, unsigned long addr,
>> unsigned long end, pgprot_t newprot, unsigned long cp_flags)
>> @@ -94,6 +171,7 @@ static long change_pte_range(struct mmu_gather *tlb,
>> bool prot_numa = cp_flags & MM_CP_PROT_NUMA;
>> bool uffd_wp = cp_flags & MM_CP_UFFD_WP;
>> bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE;
>> + int nr_ptes;
>>
>> tlb_change_page_size(tlb, PAGE_SIZE);
>> pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
>> @@ -108,8 +186,11 @@ static long change_pte_range(struct mmu_gather *tlb,
>> flush_tlb_batched_pending(vma->vm_mm);
>> arch_enter_lazy_mmu_mode();
>> do {
>> + nr_ptes = 1;
>> oldpte = ptep_get(pte);
>> if (pte_present(oldpte)) {
>> + int max_nr_ptes = (end - addr) >> PAGE_SHIFT;
>> + struct folio *folio = NULL;
>> pte_t ptent;
>>
>> /*
>> @@ -117,53 +198,12 @@ static long change_pte_range(struct mmu_gather *tlb,
>> * pages. See similar comment in change_huge_pmd.
>> */
>> if (prot_numa) {
>> - struct folio *folio;
>> - int nid;
>> - bool toptier;
>> -
>> - /* Avoid TLB flush if possible */
>> - if (pte_protnone(oldpte))
>> - continue;
>> -
>> - folio = vm_normal_folio(vma, addr, oldpte);
>> - if (!folio || folio_is_zone_device(folio) ||
>> - folio_test_ksm(folio))
>> - continue;
>> -
>> - /* Also skip shared copy-on-write pages */
>> - if (is_cow_mapping(vma->vm_flags) &&
>> - (folio_maybe_dma_pinned(folio) ||
>> - folio_maybe_mapped_shared(folio)))
>> - continue;
>> -
>> - /*
>> - * While migration can move some dirty pages,
>> - * it cannot move them all from MIGRATE_ASYNC
>> - * context.
>> - */
>> - if (folio_is_file_lru(folio) &&
>> - folio_test_dirty(folio))
>> - continue;
>> -
>> - /*
>> - * Don't mess with PTEs if page is already on the node
>> - * a single-threaded process is running on.
>> - */
>> - nid = folio_nid(folio);
>> - if (target_node == nid)
>> - continue;
>> - toptier = node_is_toptier(nid);
>> -
>> - /*
>> - * Skip scanning top tier node if normal numa
>> - * balancing is disabled
>> - */
>> - if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_NORMAL) &&
>> - toptier)
>> + nr_ptes = prot_numa_skip_ptes(&folio, vma,
>> + addr, oldpte, pte,
>> + target_node,
>> + max_nr_ptes);
>> + if (nr_ptes)
>
> I'm not really a fan of this being added (unless I'm missing something here) but
> _generally_ it's better to separate out a move and a change if you can.
>
>> continue;
>> - if (folio_use_access_time(folio))
>> - folio_xchg_access_time(folio,
>> - jiffies_to_msecs(jiffies));
>> }
>>
>> oldpte = ptep_modify_prot_start(vma, addr, pte);
>> @@ -280,7 +320,7 @@ static long change_pte_range(struct mmu_gather *tlb,
>> pages++;
>> }
>> }
>> - } while (pte++, addr += PAGE_SIZE, addr != end);
>> + } while (pte += nr_ptes, addr += nr_ptes * PAGE_SIZE, addr != end);
>> arch_leave_lazy_mmu_mode();
>> pte_unmap_unlock(pte - 1, ptl);
>>
>> --
>> 2.30.2
>>
>
> Anyway will hold off on reviewing the actual changes here until we can figure
> out whether this is event appropriate here.
next prev parent reply other threads:[~2025-06-30 11:39 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-28 11:34 [PATCH v4 0/4] Optimize mprotect() for large folios Dev Jain
2025-06-28 11:34 ` [PATCH v4 1/4] mm: Optimize mprotect() for MM_CP_PROT_NUMA by batch-skipping PTEs Dev Jain
2025-06-30 9:42 ` Ryan Roberts
2025-06-30 9:49 ` Dev Jain
2025-06-30 9:55 ` Ryan Roberts
2025-06-30 10:05 ` Dev Jain
2025-06-30 11:25 ` Lorenzo Stoakes
2025-06-30 11:39 ` Ryan Roberts [this message]
2025-06-30 11:53 ` Lorenzo Stoakes
2025-06-30 11:40 ` Dev Jain
2025-06-30 11:51 ` Lorenzo Stoakes
2025-06-30 11:56 ` Dev Jain
2025-07-02 9:37 ` Lorenzo Stoakes
2025-07-02 15:01 ` Dev Jain
2025-07-02 15:37 ` Lorenzo Stoakes
2025-06-28 11:34 ` [PATCH v4 2/4] mm: Add batched versions of ptep_modify_prot_start/commit Dev Jain
2025-06-30 10:10 ` Ryan Roberts
2025-06-30 10:17 ` Dev Jain
2025-06-30 10:35 ` Ryan Roberts
2025-06-30 10:42 ` Dev Jain
2025-06-30 12:57 ` Lorenzo Stoakes
2025-07-01 4:44 ` Dev Jain
2025-07-01 7:33 ` Ryan Roberts
2025-07-01 8:06 ` Lorenzo Stoakes
2025-07-01 8:23 ` Ryan Roberts
2025-07-01 8:34 ` Lorenzo Stoakes
2025-06-28 11:34 ` [PATCH v4 3/4] mm: Optimize mprotect() by PTE-batching Dev Jain
2025-06-28 12:39 ` Dev Jain
2025-06-30 10:31 ` Ryan Roberts
2025-06-30 11:21 ` Dev Jain
2025-06-30 11:47 ` Dev Jain
2025-06-30 11:50 ` Ryan Roberts
2025-06-30 11:53 ` Dev Jain
2025-07-01 5:47 ` Dev Jain
2025-07-01 7:39 ` Ryan Roberts
2025-06-30 12:52 ` Lorenzo Stoakes
2025-07-01 5:30 ` Dev Jain
2025-07-01 8:03 ` Ryan Roberts
2025-07-01 8:06 ` Dev Jain
2025-07-01 8:24 ` Ryan Roberts
2025-07-01 8:15 ` Lorenzo Stoakes
2025-07-01 8:30 ` Ryan Roberts
2025-07-01 8:51 ` Lorenzo Stoakes
2025-07-01 9:53 ` Ryan Roberts
2025-07-01 10:21 ` Lorenzo Stoakes
2025-07-01 11:31 ` Ryan Roberts
2025-07-01 13:40 ` Lorenzo Stoakes
2025-07-02 10:32 ` Lorenzo Stoakes
2025-07-02 15:03 ` Dev Jain
2025-07-02 15:22 ` Lorenzo Stoakes
2025-07-03 12:59 ` David Hildenbrand
2025-06-28 11:34 ` [PATCH v4 4/4] arm64: Add batched versions of ptep_modify_prot_start/commit Dev Jain
2025-06-30 10:43 ` Ryan Roberts
2025-06-29 23:05 ` [PATCH v4 0/4] Optimize mprotect() for large folios Andrew Morton
2025-06-30 3:33 ` Dev Jain
2025-06-30 10:45 ` Ryan Roberts
2025-06-30 11:22 ` Dev Jain
2025-06-30 11:17 ` Lorenzo Stoakes
2025-06-30 11:25 ` Dev Jain
2025-06-30 11:27 ` Lorenzo Stoakes
2025-06-30 11:43 ` Dev Jain
2025-07-01 0:08 ` 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=3df4db71-752f-4c59-841b-84025914870d@arm.com \
--to=ryan.roberts@arm.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=anshuman.khandual@arm.com \
--cc=baohua@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=christophe.leroy@csgroup.eu \
--cc=david@redhat.com \
--cc=dev.jain@arm.com \
--cc=hughd@google.com \
--cc=ioworker0@gmail.com \
--cc=jannh@google.com \
--cc=joey.gouly@arm.com \
--cc=kevin.brodsky@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=peterx@redhat.com \
--cc=quic_zhenhuah@quicinc.com \
--cc=vbabka@suse.cz \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=yang@os.amperecomputing.com \
--cc=yangyicong@hisilicon.com \
--cc=ziy@nvidia.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®