Re: [PATCH v3] mm: assert exclusive nid/zonenum bits at the page/folio access sites
From: Andrew Morton
Date: Wed Jun 24 2026 - 23:12:56 EST
On Thu, 25 Jun 2026 10:40:19 +0800 Hui Zhu <hui.zhu@xxxxxxxxx> wrote:
> KCSAN reports a data race between page_to_nid()/folio_pgdat() reading
> page->flags and folio_trylock()/folio_lock() concurrently doing
> test_and_set_bit_lock(PG_locked, ...) on the same word, e.g.:
>
> BUG: KCSAN: data-race in __lruvec_stat_mod_folio / shmem_get_folio_gfp
>
> The node id and zone id occupy fixed bit-ranges of page->flags that
> are set once at page init and never modified afterwards, so they can
> never overlap with the low PG_locked/PG_waiters bits touched by the
> folio lock path.
>
> ASSERT_EXCLUSIVE_BITS(mdf.f, ...) inside memdesc_nid()/memdesc_zonenum()
> checks a by-value copy of the flags word, not the actual shared
> page->flags/folio->flags being modified concurrently, so it doesn't
> reliably assert anything about the real race. Move the assertion to
> page_to_nid(), folio_nid(), page_zonenum() and folio_zonenum(), where
> flags is dereferenced directly from the page/folio.
Thanks. Sashiko is worried about CONFIG_NUMA=n:
https://sashiko.dev/#/patchset/20260625024019.838786-1-hui.zhu@xxxxxxxxx
I'm a bit surprised that these functions even exist on NUMA=n. That we
don't have simply
#else
static inline int folio_nid(const struct folio *folio)
{
return 0;
}
#endif