Re: [PATCH 04/25] mm/fbatch: lru bit set, no extra ref, while folio on per-cpu fbatch

From: Hugh Dickins

Date: Wed Sep 02 2026 - 00:07:03 EST


On Mon, 24 Aug 2026, Hugh Dickins wrote:
...
> --- a/include/linux/mm_inline.h
> +++ b/include/linux/mm_inline.h
> @@ -343,6 +343,23 @@ static inline void folio_migrate_refs(struct folio *new, const struct folio *old
> }
> #endif /* CONFIG_LRU_GEN */
>
> +enum {
> + LRU_NEXT_NEVER_TAIL = 0, /* Used by a tail's compound_head */
> + LRU_NEXT_BATCHED = 1, /* Not used by any aligned pointer */
> + NR_LRU_NEXT_FLAGS
> +};
> +
> +static __always_inline
> +bool lru_add_del_folio(struct folio *folio)
> +{
> + /* BUG_ON(folio_test_lru(folio)); */

That was a good statement of intent, but clearly I never booted
a system with that BUG_ON uncommented: it actually needs to say
/* BUG_ON(folio_test_lru(folio) && folio_ref_count(folio)); */
because once the refcount is 0, __page_cache_release() chooses to
lruvec_del_folio() before non-atomically clearing lru flags.
To be fixed when respun.

> + if (!(folio->lru_next & BIT(LRU_NEXT_BATCHED)))
> + return false;
> + folio->lru.next = LIST_POISON1;
> + /* BUG_ON(folio->lru_next & BIT(LRU_NEXT_BATCHED)); */
> + return true;
> +}
...