Re: [PATCH] mm: switch deferred split shrinker to list_lru
From: Johannes Weiner
Date: Wed Mar 11 2026 - 15:25:41 EST
On Wed, Mar 11, 2026 at 01:42:32PM -0400, Johannes Weiner wrote:
> On Wed, Mar 11, 2026 at 08:00:29PM +0300, Usama Arif wrote:
> > On 11/03/2026 18:43, Johannes Weiner wrote:
> > > @@ -3802,33 +3706,25 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n
> > > struct folio *new_folio, *next;
> > > int old_order = folio_order(folio);
> > > int ret = 0;
> > > - struct deferred_split *ds_queue;
> > > + struct list_lru_one *l;
> > >
> > > VM_WARN_ON_ONCE(!mapping && end);
> > > /* Prevent deferred_split_scan() touching ->_refcount */
> > > - ds_queue = folio_split_queue_lock(folio);
> > > + l = list_lru_lock(&deferred_split_lru, folio_nid(folio), folio_memcg(folio));
> >
> > Hello Johannes!
> >
> > I think we need folio_memcg() to be under rcu_read_lock()?
> > folio_memcg() calls obj_cgroup_memcg() which has lockdep_assert_once(rcu_read_lock_held()).
> >
> > folio_split_queue_lock() wraps split_queue_lock() under rcu_read_lock() so wasnt an issue.
>
> In this case, the caller has interrupts disabled, which implies an RCU
> read-side critical section.
>
> That's also why it's using the plain list_lru_lock(), not the irq
> variant. Same for the lruvec lock a few lines down. I followed the
> example of none of that being documented, either ;)
>
> How do folks feel about a VM_WARN_ON(!irqs_disabled()) at the top?
Okay, lockdep actually does warn. rcu_read_lock_held() is explicit and
not appeased by implicit RCU sections.
Paul pointed me to rcu_read_lock_any_held(), which we could use in
obj_cgroup_memcg() to suppress the splat and permit implicit RCU.
Or we can make rcu_read_lock() explicit in the above code.
Any preferences for how we want to handle this in MM code?