lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <28A56ACE-55E9-48A9-9EB6-696695ABB254@nvidia.com>
Date: Wed, 21 Jan 2026 13:16:23 -0500
From: Zi Yan <ziy@...dia.com>
To: Kiryl Shutsemau <kas@...nel.org>
Cc: Andrew Morton <akpm@...ux-foundation.org>,
 Muchun Song <muchun.song@...ux.dev>, David Hildenbrand <david@...nel.org>,
 Matthew Wilcox <willy@...radead.org>, Usama Arif <usamaarif642@...il.com>,
 Frank van der Linden <fvdl@...gle.com>, Oscar Salvador <osalvador@...e.de>,
 Mike Rapoport <rppt@...nel.org>, Vlastimil Babka <vbabka@...e.cz>,
 Lorenzo Stoakes <lorenzo.stoakes@...cle.com>, Baoquan He <bhe@...hat.com>,
 Michal Hocko <mhocko@...e.com>, Johannes Weiner <hannes@...xchg.org>,
 Jonathan Corbet <corbet@....net>, kernel-team@...a.com, linux-mm@...ck.org,
 linux-kernel@...r.kernel.org, linux-doc@...r.kernel.org
Subject: Re: [PATCHv4 10/14] mm: Drop fake head checks

On 21 Jan 2026, at 11:22, Kiryl Shutsemau wrote:

> With fake head pages eliminated in the previous commit, remove the
> supporting infrastructure:
>
>   - page_fixed_fake_head(): no longer needed to detect fake heads;
>   - page_is_fake_head(): no longer needed;
>   - page_count_writable(): no longer needed for RCU protection;
>   - RCU read_lock in page_ref_add_unless(): no longer needed;
>
> This substantially simplifies compound_head() and page_ref_add_unless(),
> removing both branches and RCU overhead from these hot paths.
>
> Signed-off-by: Kiryl Shutsemau <kas@...nel.org>
> Reviewed-by: Muchun Song <muchun.song@...ux.dev>
> ---
>  include/linux/page-flags.h | 93 ++------------------------------------
>  include/linux/page_ref.h   |  8 +---
>  2 files changed, 4 insertions(+), 97 deletions(-)
>
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index e16a4bc82856..660f9154a211 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -221,102 +221,15 @@ static __always_inline bool compound_info_has_mask(void)
>  	return is_power_of_2(sizeof(struct page));
>  }
>
> -#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>  DECLARE_STATIC_KEY_FALSE(hugetlb_optimize_vmemmap_key);
>
> -/*
> - * Return the real head page struct iff the @page is a fake head page, otherwise
> - * return the @page itself. See Documentation/mm/vmemmap_dedup.rst.
> - */
> -static __always_inline const struct page *page_fixed_fake_head(const struct page *page)
> -{
> -	if (!static_branch_unlikely(&hugetlb_optimize_vmemmap_key))
> -		return page;
> -
> -	/* Fake heads only exists if compound_info_has_mask() is true */
> -	if (!compound_info_has_mask())
> -		return page;
> -
> -	/*
> -	 * Only addresses aligned with PAGE_SIZE of struct page may be fake head
> -	 * struct page. The alignment check aims to avoid access the fields (
> -	 * e.g. compound_info) of the @page[1]. It can avoid touch a (possibly)
> -	 * cold cacheline in some cases.
> -	 */
> -	if (IS_ALIGNED((unsigned long)page, PAGE_SIZE) &&
> -	    test_bit(PG_head, &page->flags.f)) {
> -		/*
> -		 * We can safely access the field of the @page[1] with PG_head
> -		 * because the @page is a compound page composed with at least
> -		 * two contiguous pages.
> -		 */
> -		unsigned long info = READ_ONCE(page[1].compound_info);
> -
> -		/* See set_compound_head() */
> -		if (likely(info & 1)) {
> -			unsigned long p = (unsigned long)page;
> -
> -			return (const struct page *)(p & info);
> -		}
> -	}
> -	return page;
> -}
> -

<snip>

>  static __always_inline unsigned long _compound_head(const struct page *page)
>  {
>  	unsigned long info = READ_ONCE(page->compound_info);
>
>  	/* Bit 0 encodes PageTail() */
>  	if (!(info & 1))
> -		return (unsigned long)page_fixed_fake_head(page);
> +		return (unsigned long)page;

Is this right? Assuming 64B struct page and 4KB page size, thus 64 struct pages
in a page, the 64th struct page (0-indexed) is mapped to the head page and
has !(info & 1). But _compound_head() should return page & info here.
Am I missing something? Thanks.


Best Regards,
Yan, Zi

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ