From: "Hui Zhu" <hui.zhu@linux.dev>
To: "David Hildenbrand (Arm)" <david@kernel.org>,
"Leon Hwang" <leon.hwang@linux.dev>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Mike Rapoport" <rppt@kernel.org>,
"Suren Baghdasaryan" <surenb@google.com>,
"Michal Hocko" <mhocko@suse.com>,
"Kairui Song" <kasong@tencent.com>,
"Qi Zheng" <qi.zheng@linux.dev>,
"Shakeel Butt" <shakeel.butt@linux.dev>,
"Barry Song" <baohua@kernel.org>,
"Axel Rasmussen" <axelrasmussen@google.com>,
"Yuanchu Xie" <yuanchu@google.com>, "Wei Xu" <weixugc@google.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: "Hui Zhu" <zhuhui@kylinos.cn>
Subject: Re: [PATCH v7] mm: assert exclusive nid/zonenum bits at the page/folio access sites
Date: Mon, 29 Jun 2026 03:32:00 +0000 [thread overview]
Message-ID: <7561266d0aedbb55f3f67090fb2493f7a899b66e@linux.dev> (raw)
In-Reply-To: <e46ba0c9-6a24-45e5-99f8-b4f454887f50@kernel.org>
2026年6月26日 17:09, "David Hildenbrand (Arm)" <david@kernel.org mailto:david@kernel.org?to=%22David%20Hildenbrand%20(Arm)%22%20%3Cdavid%40kernel.org%3E > 写到:
>
> >
> > >
> > > static inline enum zone_type folio_zonenum(const struct folio *folio)
> > > {
> > > +#if ZONES_WIDTH != 0
> > > + ASSERT_EXCLUSIVE_BITS(folio->flags, ZONES_MASK << ZONES_PGSHIFT);
> > > +#endif
> > > return memdesc_zonenum(folio->flags);
> > > }
> > >
> >
> > Better to factor out a common macro alongside a comment for these two '#if'?
> >
> Yes.
>
> And while looking at it, doesn't memdesc_section have similar problems? And
> there are other callers of memdesc_zonenum we wouldn't handle. So the
> macro approach is only partially helpful I thing.
>
> Maybe we should just pass by reference and fixup all callers? Ends up the cleanest.
>
Hi David,
I think pass by reference is better than macro.
Would you like to send this out as a formal patch yourself?
Or would you prefer I include it in my next version with your
Signed-off-by?
Best,
Hui
> Untested:
>
> From fb9b4e8c1d0419b960dc0cd4738d19d80d1fe14f Mon Sep 17 00:00:00 2001
> From: "David Hildenbrand (Arm)" <david@kernel.org>
> Date: Fri, 26 Jun 2026 11:06:39 +0200
> Subject: [PATCH] mm: fix KASAN memdec_flags checks for zone/node/section
>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> ---
> include/asm-generic/memory_model.h | 2 +-
> include/linux/mm.h | 23 +++++++++++++++--------
> include/linux/mm_inline.h | 4 ++--
> include/linux/mmzone.h | 24 ++++++++++++------------
> mm/page_alloc.c | 6 +++---
> mm/slab.h | 2 +-
> mm/sparse.c | 2 +-
> 7 files changed, 35 insertions(+), 28 deletions(-)
>
> diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
> index efa6610acbc79..f8404bc7773c2 100644
> --- a/include/asm-generic/memory_model.h
> +++ b/include/asm-generic/memory_model.h
> @@ -53,7 +53,7 @@ static inline int pfn_valid(unsigned long pfn)
> */
> #define __page_to_pfn(pg) \
> ({ const struct page *__pg = (pg); \
> - int __sec = memdesc_section(__pg->flags); \
> + int __sec = memdesc_section(&__pg->flags); \
> (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
> })
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 485df9c2dbddb..3111e4a6c9c4c 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2286,22 +2286,28 @@ static inline int page_zone_id(struct page *page)
> }
>
> #ifdef NODE_NOT_IN_PAGE_FLAGS
> -int memdesc_nid(memdesc_flags_t mdf);
> +int memdesc_nid(const memdesc_flags_t *mdf);
> +#elif defined(CONFIG_NUMA)
> +static inline int memdesc_nid(const memdesc_flags_t *mdf)
> +{
> + ASSERT_EXCLUSIVE_BITS(mdf->f, NODES_MASK << NODES_PGSHIFT);
> + return (mdf->f >> NODES_PGSHIFT) & NODES_MASK;
> +}
> #else
> -static inline int memdesc_nid(memdesc_flags_t mdf)
> +static inline int memdesc_nid(const memdesc_flags_t *mdf)
> {
> - return (mdf.f >> NODES_PGSHIFT) & NODES_MASK;
> + return 0;
> }
> #endif
>
> static inline int page_to_nid(const struct page *page)
> {
> - return memdesc_nid(PF_POISONED_CHECK(page)->flags);
> + return memdesc_nid(&PF_POISONED_CHECK(page)->flags);
> }
>
> static inline int folio_nid(const struct folio *folio)
> {
> - return memdesc_nid(folio->flags);
> + return memdesc_nid(&folio->flags);
> }
>
> #ifdef CONFIG_NUMA_BALANCING
> @@ -2541,12 +2547,13 @@ static inline void set_page_section(struct page *page, unsigned long section)
> page->flags.f |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
> }
>
> -static inline unsigned long memdesc_section(memdesc_flags_t mdf)
> +static inline unsigned long memdesc_section(const memdesc_flags_t *mdf)
> {
> - return (mdf.f >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> + ASSERT_EXCLUSIVE_BITS(mdf->f, SECTIONS_MASK << SECTIONS_PGSHIFT);
> + return (mdf->f >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> }
> #else /* !SECTION_IN_PAGE_FLAGS */
> -static inline unsigned long memdesc_section(memdesc_flags_t mdf)
> +static inline unsigned long memdesc_section(const memdesc_flags_t *mdf)
> {
> return 0;
> }
> diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
> index a8430a7ae0544..efcddb9925add 100644
> --- a/include/linux/mm_inline.h
> +++ b/include/linux/mm_inline.h
> @@ -650,7 +650,7 @@ static inline bool vma_has_recency(const struct vm_area_struct *vma)
> static inline size_t num_pages_contiguous(struct page **pages, size_t nr_pages)
> {
> struct page *cur_page = pages[0];
> - unsigned long section = memdesc_section(cur_page->flags);
> + unsigned long section = memdesc_section(&cur_page->flags);
> size_t i;
>
> for (i = 1; i < nr_pages; i++) {
> @@ -660,7 +660,7 @@ static inline size_t num_pages_contiguous(struct page **pages, size_t nr_pages)
> * In unproblematic kernel configs, page_to_section() == 0 and
> * the whole check will get optimized out.
> */
> - if (memdesc_section(cur_page->flags) != section)
> + if (memdesc_section(&cur_page->flags) != section)
> break;
> }
>
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index ca27121871475..19e709d7a13de 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1272,31 +1272,31 @@ static inline bool zone_is_empty(const struct zone *zone)
> #define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1)
> #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1)
>
> -static inline enum zone_type memdesc_zonenum(memdesc_flags_t flags)
> +static inline enum zone_type memdesc_zonenum(const memdesc_flags_t *flags)
> {
> - ASSERT_EXCLUSIVE_BITS(flags.f, ZONES_MASK << ZONES_PGSHIFT);
> - return (flags.f >> ZONES_PGSHIFT) & ZONES_MASK;
> + ASSERT_EXCLUSIVE_BITS(flags->f, ZONES_MASK << ZONES_PGSHIFT);
> + return (flags->f >> ZONES_PGSHIFT) & ZONES_MASK;
> }
>
> static inline enum zone_type page_zonenum(const struct page *page)
> {
> - return memdesc_zonenum(page->flags);
> + return memdesc_zonenum(&page->flags);
> }
>
> static inline enum zone_type folio_zonenum(const struct folio *folio)
> {
> - return memdesc_zonenum(folio->flags);
> + return memdesc_zonenum(&folio->flags);
> }
>
> #ifdef CONFIG_ZONE_DEVICE
> -static inline bool memdesc_is_zone_device(memdesc_flags_t mdf)
> +static inline bool memdesc_is_zone_device(const memdesc_flags_t *mdf)
> {
> return memdesc_zonenum(mdf) == ZONE_DEVICE;
> }
>
> static inline struct dev_pagemap *page_pgmap(const struct page *page)
> {
> - VM_WARN_ON_ONCE_PAGE(!memdesc_is_zone_device(page->flags), page);
> + VM_WARN_ON_ONCE_PAGE(!memdesc_is_zone_device(&page->flags), page);
> return page_folio(page)->pgmap;
> }
>
> @@ -1311,9 +1311,9 @@ static inline struct dev_pagemap *page_pgmap(const struct page *page)
> static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
> const struct page *b)
> {
> - if (memdesc_is_zone_device(a->flags) != memdesc_is_zone_device(b->flags))
> + if (memdesc_is_zone_device(&a->flags) != memdesc_is_zone_device(&b->flags))
> return false;
> - if (!memdesc_is_zone_device(a->flags))
> + if (!memdesc_is_zone_device(&a->flags))
> return true;
> return page_pgmap(a) == page_pgmap(b);
> }
> @@ -1321,7 +1321,7 @@ static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
> extern void memmap_init_zone_device(struct zone *, unsigned long,
> unsigned long, struct dev_pagemap *);
> #else
> -static inline bool memdesc_is_zone_device(memdesc_flags_t mdf)
> +static inline bool memdesc_is_zone_device(const memdesc_flags_t *mdf)
> {
> return false;
> }
> @@ -1338,12 +1338,12 @@ static inline struct dev_pagemap *page_pgmap(const struct page *page)
>
> static inline bool is_zone_device_page(const struct page *page)
> {
> - return memdesc_is_zone_device(page->flags);
> + return memdesc_is_zone_device(&page->flags);
> }
>
> static inline bool folio_is_zone_device(const struct folio *folio)
> {
> - return memdesc_is_zone_device(folio->flags);
> + return memdesc_is_zone_device(&folio->flags);
> }
>
> static inline bool is_zone_movable_page(const struct page *page)
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index ee902a468c2f5..020a97ca018e9 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -6904,15 +6904,15 @@ static void __free_contig_range_common(unsigned long pfn, unsigned long nr_pages
> continue;
> }
>
> - if (start && memdesc_section(page->flags) != start_sec) {
> + if (start && memdesc_section(&page->flags) != start_sec) {
> free_prepared_contig_range(start, i - nr_start);
> start = page;
> nr_start = i;
> - start_sec = memdesc_section(page->flags);
> + start_sec = memdesc_section(&page->flags);
> } else if (!start) {
> start = page;
> nr_start = i;
> - start_sec = memdesc_section(page->flags);
> + start_sec = memdesc_section(&page->flags);
> }
> }
>
> diff --git a/mm/slab.h b/mm/slab.h
> index bf2f87acf5e3a..1ae8e6084ba32 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -155,7 +155,7 @@ static inline void *slab_address(const struct slab *slab)
>
> static inline int slab_nid(const struct slab *slab)
> {
> - return memdesc_nid(slab->flags);
> + return memdesc_nid(&slab->flags);
> }
>
> static inline pg_data_t *slab_pgdat(const struct slab *slab)
> diff --git a/mm/sparse.c b/mm/sparse.c
> index 16ac6df3c89fa..8e38477645131 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -43,7 +43,7 @@ static u8 section_to_node_table[NR_MEM_SECTIONS] __cacheline_aligned;
> static u16 section_to_node_table[NR_MEM_SECTIONS] __cacheline_aligned;
> #endif
>
> -int memdesc_nid(memdesc_flags_t mdf)
> +int memdesc_nid(const memdesc_flags_t *mdf)
> {
> return section_to_node_table[memdesc_section(mdf)];
> }
> --
> 2.43.0
>
> --
> Cheers,
>
> David
>
next prev parent reply other threads:[~2026-06-29 3:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 3:20 [PATCH v7] mm: assert exclusive nid/zonenum bits at the page/folio access sites Hui Zhu
2026-06-26 4:54 ` kernel test robot
2026-06-26 4:54 ` kernel test robot
2026-06-26 5:04 ` Leon Hwang
2026-06-26 9:09 ` David Hildenbrand (Arm)
2026-06-29 3:32 ` Hui Zhu [this message]
2026-06-29 6:22 ` David Hildenbrand (Arm)
2026-06-26 6:05 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7561266d0aedbb55f3f67090fb2493f7a899b66e@linux.dev \
--to=hui.zhu@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=david@kernel.org \
--cc=kasong@tencent.com \
--cc=leon.hwang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=qi.zheng@linux.dev \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=weixugc@google.com \
--cc=yuanchu@google.com \
--cc=zhuhui@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.