From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-178.mta0.migadu.com (out-178.mta0.migadu.com [91.218.175.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 307B63D76 for ; Sun, 26 Jul 2026 04:30:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785040239; cv=none; b=konmsuxC05c8HsavSvzXiKVId1JVtc8DXxp/8bN7uaGZH6ZX9chf0n7IKWIFFX04Yp6wYafpyx0OjcxHxo/KtjV2P4dAFGqYpwdMFqerB0K9bo03D66xQvTPAponYRUPWKRqYoxF7yryJSRGfxH0QQT9cbcOrLkHPdQ8aIQ8X9c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785040239; c=relaxed/simple; bh=myJGL+vwFIPIkT0hYPcAVLtTkahx+p8D+G1AKXagjkA=; h=Content-Type:Mime-Version:Subject:From:In-Reply-To:Date:Cc: Message-Id:References:To; b=qkzP9vxU3B8z6NCcncXYD1pDkrREB44GTuGSqzkhBxPj15YOOqTNcYcIGyqHG/tk2adBcQSHyuHkFlZtUjH6umTO4fm9J7YD7/pHWF22/uyEZuX33ORckEGnIUU2vRs8cWPNeidsFhdwnXQn+UwP4iBWicFX04W1Q1+u14eqS+E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=GiFdDpLs; arc=none smtp.client-ip=91.218.175.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="GiFdDpLs" Content-Type: text/plain; charset=utf-8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785040233; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fk0u0C46PSOxjn1bmvTNC2VObm0AdVqBqTpTwS4dVgg=; b=GiFdDpLsCY9O1i08dsREM5xkTYbyL+dVDaGJel+m+k75TqnYJ//NhZM7IkH78BNqN+0Ivj T/D3mNCoYJOIdJLpLPcHgCDLByC4Hoz+CjiLxoA5m3MA5p1hjFFd7O15tEQe2b+mTFSaLH 9a0ivHwWzxxZsjbaxUhaWVdqbywg/pU= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.600.51.1.1\)) Subject: Re: [PATCH v2 03/17] mm/mm_init: skip initializing shared vmemmap tail pages X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Muchun Song In-Reply-To: <20260720093127.540540-4-songmuchun@bytedance.com> Date: Sun, 26 Jul 2026 12:30:17 +0800 Cc: Andrew Morton , Oscar Salvador , David Hildenbrand , Mike Rapoport , Vlastimil Babka , Lorenzo Stoakes , Michal Hocko , David Laight , linux-mm@kvack.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Message-Id: <5005C7D3-B3ED-4C62-B611-8465D2BC69FD@linux.dev> References: <20260720093127.540540-1-songmuchun@bytedance.com> <20260720093127.540540-4-songmuchun@bytedance.com> To: Muchun Song X-Migadu-Flow: FLOW_OUT > On Jul 20, 2026, at 17:31, Muchun Song = wrote: >=20 > memmap_init_range() initializes every struct page in the target range. > For compound pages with vmemmap optimization, the tail struct pages = are > backed by a shared vmemmap page. >=20 > Initializing those tail struct pages would overwrite the shared > vmemmap page contents, requiring users such as HugeTLB to restore the > metadata afterwards. >=20 > Track the compound order for HVO-backed sections and use that metadata > to detect struct pages that fall into the shared tail vmemmap range. > Skip those shared tail pages in memmap_init_range(), then initialize > pageblock migratetypes for the processed range with a helper after the > per-page initialization loop. >=20 > The !SPARSEMEM __pfn_to_section() stub is needed only for the build: > memmap_init_range() references __pfn_to_section() after checking > pfn_vmemmap_optimizable(), and !SPARSEMEM builds still have to compile > that code even though pfn_vmemmap_optimizable() folds to false. >=20 > This is a preparatory change for consolidating handling across users = of > vmemmap optimization, and it also avoids redundant initialization of > shared tail vmemmap pages during early boot. >=20 > Signed-off-by: Muchun Song > --- > v2: > - Fold section order tracking into the first user instead of keeping a > standalone API-only patch (suggested by Mike Rapoport) > - Rename page_vmemmap_optimizable() to pfn_vmemmap_optimizable() and > pass a PFN directly (suggested by Mike Rapoport) > - Initialize pageblock migratetypes from a helper after the per-page > loop (suggested by Mike Rapoport) > - Use a 1G PFN chunk for cond_resched() in the pageblock helper > (suggested by Mike Rapoport) > - Guard section_order() with CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP so > it returns 0 when HVO is disabled and lets the compiler optimize the > code as much as possible (suggested by Mike Rapoport) > - Explain why the !SPARSEMEM __pfn_to_section() stub belongs here > (suggested by Mike Rapoport) > --- > include/linux/mmzone.h | 14 ++++++++++++++ > mm/mm_init.c | 33 +++++++++++++++++---------------- > mm/sparse.h | 23 +++++++++++++++++++++++ > 3 files changed, 54 insertions(+), 16 deletions(-) >=20 > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > index 82b0155d886f..2a32101d55e6 100644 > --- a/include/linux/mmzone.h > +++ b/include/linux/mmzone.h > @@ -2011,6 +2011,14 @@ struct mem_section { > unsigned long section_mem_map; >=20 > struct mem_section_usage *usage; > +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP > + /* > + * Normally, sections hold regular (order-0) pages. However, for > + * sections with HVO enabled, this tracks the compound page = order > + * to enable deduplication of redundant vmemmap pages. > + */ > + unsigned int order; > +#endif > #ifdef CONFIG_PAGE_EXTENSION > /* > * If SPARSEMEM, pgdat doesn't have page_ext pointer. We use > @@ -2365,8 +2373,14 @@ static inline unsigned long = next_present_section_nr(unsigned long section_nr) > #endif >=20 > #else > +struct mem_section; > + > #define sparse_vmemmap_init_nid_early(_nid) do {} while (0) > #define pfn_in_present_section pfn_valid > +static inline struct mem_section *__pfn_to_section(unsigned long pfn) > +{ > + return NULL; > +} I'd like to propose an alternative implementation that doesn't require exposing the mem_section. The idea is to add a new helper function, pfn_to_section_order(), so that for non-sparse-memory configurations, the mem_section concept stays hidden internally. I'd really appreciate any thoughts or concerns =E2=80=94 if everyone is comfortable with it, I = can go ahead and implement this in the next version. Muchun, Thanks.