Re: [PATCH v2] mm: unqueue deferred split folios outside the lruvec lock
From: Barry Song
Date: Mon Oct 19 2026 - 01:56:30 EST
On Mon, Oct 19, 2026 at 1:38 PM Lance Yang <lance.yang@xxxxxxxxx> wrote:
>
>
>
> On 2026/10/17 08:45, Joanne Koong wrote:
> > move_folios_to_lru(), folio_batch_move_lru() and folios_put_refs() call
> > folio_unqueue_deferred_split() on folios where the refcount has dropped
> > to zero. In these paths, folio_unqueue_deferred_split() is called with
> > the lruvec lock often held (move_folios_to_lru() always holds it and
> > folio_batch_move_lru()/folios_put_refs() usually hold it for every folio
> > in the batch except the first). However, it's not needed to hold the
> > lruvec lock.
> >
> > The lruvec lock protects folio->lru and the reclaim LRU lists whereas
> > the deferred split queue lives on folio->_deferred_list in
> > deferred_split_lru. The deferred_split_lru is a list_lru with its own
> > per-memcg per-node lock.
> >
> > There are already other existing callers that call
> > folio_unqueue_deferred_split() without holding the lruvec lock (eg
> > __folio_put(), shrink_folio_list(), __folio_migrate_mapping(), ...).
> >
> > Add folio_batch_unqueue_deferred_split() and use it in
> > move_folios_to_lru(), folio_batch_move_lru(), and folios_put_refs() to
> > unqueue each batch of zero-refcount folios from the deferred split list
> > after the lruvec lock is released and before
> > mem_cgroup_uncharge_folios(). This helps shorten the lruvec lock's
> > critical sections, which run with IRQs disabled and are highly
> > contended.
> >
> > Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx>
> > ---
> > This patch came out of a discussion about splitting underused mTHP folios [1],
> > where queueing small mTHP folios on the deferred split list was found to
> > regress Barry's fault microbenchmark. The cost turned out to be the unqueue
> > running under the lruvec lock rather than contention on the deferred split
> > queue itself. Testing this patch on top of the series in [1] with the same
> > microbenchmark, queueing every 16k folio went from a 15% runtime cost to
> > noise, with lruvec lock wait dropping from 491 seconds to 38 seconds (most of
> > that contention then moves to the deferred split list_lru lock, but runtime
> > still drops back to the unqueued baseline).
>
> Looks great :) Could you also keep the benchmark results above the '---'?
> They'd be useful to have in the changelog, along with the test setup.
+1. I guess Joanne didn't include it in the changelog because the benchmark
depends on her patchset, which hasn't been merged into mainline yet. But it
should be fine to include the relevant details in the changelog since there
is already a link to Joanne's patchset.
Joanne, could you also link your patchset and explain which patchset you
used to collect the data?
>
> With that, LGTM!
>
> Reviewed-by: Lance Yang <lance.yang@xxxxxxxxx>