Subject: Re: [PATCH] arm64: Implement clear_pages()

From: Catalin Marinas <[email-masked]>
Date: Wed, 4 Mar 2026 08:49:19 +0000

On Wed, Mar 04, 2026 at 12:05:04AM -0800, Ankur Arora wrote:
> Linus Walleij <[email-masked]> writes:
> > On Tue, Mar 3, 2026 at 3:46 PM Will Deacon <[email-masked]> wrote:
> >> If we have CPUs that are this sensitive to branches, perhaps we'd be
> >> better off taking the opposite approach and moving more code into C
> >> so that the compiler can optimise the control flow for us?
> >
> > Hm! That would be to create a default clear_page() in
> > <linux/mm.h> and simply delete the existing lib/clear_page.S
> > and let the default kick in.
> >
> > Right now every arch is implementing it custom.
> > Maybe for no reason in some cases, I could try it!
> >
> > I doubt the compiler would emit this part though:
> >
> > #ifdef CONFIG_AS_HAS_MOPS
> > (...)
> > alternative_else_nop_endif
> >         setpn   [x0]!, x1!, xzr
> >         setmn   [x0]!, x1!, xzr
> >         seten   [x0]!, x1!, xzr
> >         ret

It won't generate it. It wouldn't be a pure C but have some inline asm.

Anyway, I'm fine with the .S file, I just wonder whether the DCZID_EL0
read inside the inner loop is causing problems (not the FEAT_MOPS
variant).

> > Three instructions to clear all pages. But maybe that is not good
> > if this is a gigabyte, and the per-page loop provides a good breather
> > preemption point in that case, and then we just shouldn't touch
> > anything.
> 
> The code in folio_zero_user (clear_contig_highpages()) takes care of
> chunking up the clearing based on preemption model.
> The idea being that if you are running with preempt=none or voluntary
> then you might want to call cond_resched(), say every 32MB or so.
> 
> If you are running with preempt=full or preempt=lazy, then it would
> just clear a full GB page.
> 
> That would need the set[mpe]n instructions to be interruptible though.
> (Seems to me that that is true but maybe someone could confirm.)

Yes, they are interruptible (the SETM). The x0, x1 register are left in
a state that the SETM can be restarted from where it was interrupted.

-- 
Catalin