Re: [PATCH RFC v2] mm: introduce copy_mc_highpages() and batch copy in folio_mc_copy()
From: Garg, Shivank
Date: Mon Oct 19 2026 - 09:18:57 EST
On Mon, 2026-10-19 at 14:23 +0200, David Hildenbrand (Arm) wrote:
> > > +}
> > > +#else
> > > +
> > > +#define COPY_MC_PAGES_NON_PREEMPT_BATCH 1
> >
> > I would suggest that perhaps this should be the fallback for non-preemptible
> > models. But it gets a little weird with PREEMPT_DYNAMIC I think?
>
> Why can't we just use PROCESS_PAGES_NON_PREEMPT_BATCH where we have similar
> handling already?
>
> >
I did not reuse PROCESS_PAGES_NON_PREEMPT_BATCH because it depends on
whether clear_pages is defined. While COPY_MC_PAGES_NON_PREEMPT_BATCH
depends on copy_mc_to_kernel and other constraints. So, using a single
param for both would make it more messy.
However as Pedro pointed, most architectures are full preempt/preempt lazy,
and with this commit 7dadeaa6e851 ("sched: Further restrict the
preemption modes"), for PREEMPT_DYNAMIC, preempt=none and preempt=voluntary
are rejected at boot. preempt_model_preemptible() is therefore always
true for this case.
So, this can be simplfied to drop the COPY_MC_PAGES_NON_PREEMPT_BATCH.
> > > +
> > > +static inline int copy_mc_highpages(struct page *to, struct page *from,
> > > + unsigned long nr_pages)
> > > +{
> > > + unsigned long i;
> > > +
> > > + for (i = 0; i < nr_pages; i++)
> > > + if (copy_mc_highpage(to + i, from + i))
> > > + return -EHWPOISON;
> > > + return 0;
> > > +}
> > > +#endif
> > > +
> > > static inline void memcpy_page(struct page *dst_page, size_t dst_off,
> > > struct page *src_page, size_t src_off,
> > > size_t len)
> > > diff --git a/mm/util.c b/mm/util.c
> > > index 7f374bb8bf36..5015cfdfeaa5 100644
> > > --- a/mm/util.c
> > > +++ b/mm/util.c
> > > @@ -763,13 +763,23 @@ EXPORT_SYMBOL(folio_copy);
> > >
> > >
> > > int folio_mc_copy(struct folio *dst, struct folio *src)
> > > {
> > > - long nr = folio_nr_pages(src);
> > > - long i = 0;
> > > + const unsigned long nr_pages = folio_nr_pages(src);
> > > + /*
> > > + * Copy the largest extent possible to allow for architecture specific
> > > + * extent based optimizations. copy_mc_highpages() does not call
> > > + * cond_resched(), so limit the unit size when running under
> > > + * non-preemptible scheduling models.
> > > + */
> > > + const unsigned long unit = preempt_model_preemptible() ?
> > > + nr_pages : COPY_MC_PAGES_NON_PREEMPT_BATCH;
> >
> > See? now mm is aware of preemption models! eww!
>
> Yeah, we have that in clear_contig_highpages() already, which is getting
> replicated here for copying instead of zeroing.