From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (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 693E3364038 for ; Wed, 1 Apr 2026 02:42:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775011358; cv=none; b=ZsD72BzHL7oU/Ui73cy4E3hcfiqKcQ3QQHnS9Rqf8DJURu/DbNe4Ay4PCehPVUxilEjnWPfOMq4/8A827z9grst+geYmBa3AJ2ytaNo5MjP7r3mZLADxiKumU8u6OvJVUElqvgzlLskWXV1oAd2qg72QH/vTVfkM9q40VCAl9CE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775011358; c=relaxed/simple; bh=VXqC11i46keVveaBvV+mICk8RMgHWURoQi8thRRyDfg=; h=Content-Type:Mime-Version:Subject:From:In-Reply-To:Date:Cc: Message-Id:References:To; b=NeLKZPW3GCYFdYqkL0hWwUDs5mTzVcZeZzkhJsuuSfunC53F8JByHJkmDB7Q3Oi0+YoN6P8zKSMsaJgeDV7SUjs8mg/uCML/PVCGJFGVlo+jbrI3+bY68dZk9ZinCbJbpaV0B/w+hf9wu5kjYyNDU/XKZgaRPRxvmrXjyYKsk/A= 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=AWD8gD2y; arc=none smtp.client-ip=91.218.175.185 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="AWD8gD2y" Content-Type: text/plain; charset=utf-8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1775011341; 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=OYzgJhPBELX+5svIaMHyyrG4VC9DWWPsk64e6cKGVmQ=; b=AWD8gD2yYWhtLaaaFtHHTzd1ZrylQ42YS7/HwqG4IQZqmc2IQngtGJ4Umql4wmBnVv8uGq FoOU9skiW9PmptHxqrkm7Xn6snIs6UVKy+AEph/5JmLJS6wPse+LzmOQINMandy2PiOlwv 4cRE/oLBStgnXB9LaUJrkHWQ6y1ffDM= 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.400.21\)) Subject: Re: [PATCH] mm/sparse: fix preinited section_mem_map clobbering on failure path X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Muchun Song In-Reply-To: <17246161-f314-45da-933a-770231ef2a49@kernel.org> Date: Wed, 1 Apr 2026 10:41:42 +0800 Cc: Muchun Song , Andrew Morton , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Frank van der Linden , linux-mm@kvack.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Message-Id: <2183487D-0CED-4BEF-84D7-4439F3386584@linux.dev> References: <20260331113724.2080833-1-songmuchun@bytedance.com> <17246161-f314-45da-933a-770231ef2a49@kernel.org> To: "David Hildenbrand (Arm)" X-Migadu-Flow: FLOW_OUT > On Apr 1, 2026, at 04:42, David Hildenbrand (Arm) = wrote: >=20 > On 3/31/26 13:37, Muchun Song wrote: >> sparse_init_nid() is careful to leave alone every section whose = vmemmap >> has already been set up by sparse_vmemmap_init_nid_early(); it only >> clears section_mem_map for the rest: >>=20 >> if (!preinited_vmemmap_section(ms)) >> ms->section_mem_map =3D 0; >>=20 >> A leftover line after that conditional block >>=20 >> ms->section_mem_map =3D 0; >>=20 >> was supposed to be deleted but was missed in the failure path, = causing the >> field to be overwritten for all sections when memory allocation = fails, >> effectively destroying the pre-initialization check. >>=20 >> Drop the stray assignment so that preinited sections retain their >> already valid state. >>=20 >> Fixes: d65917c42373 ("mm/sparse: allow for alternate vmemmap section = init at boot") >> Signed-off-by: Muchun Song >> --- >> mm/sparse.c | 1 - >> 1 file changed, 1 deletion(-) >>=20 >> diff --git a/mm/sparse.c b/mm/sparse.c >> index c2eb36bfb86d..3a14b733bf71 100644 >> --- a/mm/sparse.c >> +++ b/mm/sparse.c >> @@ -584,7 +584,6 @@ static void __init sparse_init_nid(int nid, = unsigned long pnum_begin, >> ms =3D __nr_to_section(pnum); >> if (!preinited_vmemmap_section(ms)) >> ms->section_mem_map =3D 0; >> - ms->section_mem_map =3D 0; >=20 >=20 > Acked-by: David Hildenbrand (Arm) Thanks. >=20 > I have some cleanup patches lying around that cleanup that code = heavily. > I think I get rid of this questionable "failed to allocate" case = entirely. It's truly a coincidence =E2=80=94 I also have a piece of code locally that does something similar. Since allocation failure would also affect subsequent startup processes, I simply made it panic when allocation fails. mm: panic on memory allocation failure in sparse_init_nid() When vmemmap pages allocation or usemap allocation fails, = sparse_init_nid() currently only marks the corresponding section as non-present. = However, subsequent code like memmap_init() iterating over PFNs does not = check for non-present sections, leading to invalid memory access (additional, subsection_map_init() accessing the unallocated usemap as well). It is complex to audit and fix all boot-time PFN iterators to handle = these partially initialized sections correctly. Since vmemmap and usemap = allocation failures are extremely rare during early boot, the more appropriate = approach is to expose the problem as early as possible. Therefore, use BUG_ON() to panic immediately if allocation fails, = instead of attempting a partial recovery that leads to obscure crashes later. Signed-off-by: Muchun Song diff --git a/mm/sparse.c b/mm/sparse.c index 1b017026925e..bb0b86a4f3ef 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -354,19 +354,14 @@ static void __init sparse_init_nid(int nid, = unsigned long pnum_begin, unsigned long map_count) { unsigned long pnum; - struct page *map; - struct mem_section *ms; - - if (sparse_usage_init(nid, map_count)) { - pr_err("%s: node[%d] usemap allocation failed", = __func__, nid); - goto failed; - } + BUG_ON(sparse_usage_init(nid, map_count)); sparse_buffer_init(map_count * section_map_size(), nid); sparse_vmemmap_init_nid_early(nid); for_each_present_section_nr(pnum_begin, pnum) { + struct mem_section *ms; unsigned long pfn =3D section_nr_to_pfn(pnum); if (pnum >=3D pnum_end) @@ -374,16 +369,11 @@ static void __init sparse_init_nid(int nid, = unsigned long pnum_begin, ms =3D __nr_to_section(pnum); if (!preinited_vmemmap_section(ms)) { + struct page *map; + map =3D __populate_section_memmap(pfn, = PAGES_PER_SECTION, - nid, NULL, NULL); - if (!map) { - pr_err("%s: node[%d] memory map backing = failed. Some memory will not be available.", - __func__, nid); - pnum_begin =3D pnum; - sparse_usage_fini(); - sparse_buffer_fini(); - goto failed; - } + nid, NULL, = NULL); + BUG_ON(!map); = memmap_boot_pages_add(DIV_ROUND_UP(PAGES_PER_SECTION * sizeof(struct = page), PAGE_SIZE)); sparse_init_early_section(nid, map, pnum, 0); @@ -391,19 +381,6 @@ static void __init sparse_init_nid(int nid, = unsigned long pnum_begin, } sparse_usage_fini(); sparse_buffer_fini(); - return; -failed: - /* - * We failed to allocate, mark all the following pnums as not = present, - * except the ones already initialized earlier. - */ - for_each_present_section_nr(pnum_begin, pnum) { - if (pnum >=3D pnum_end) - break; - ms =3D __nr_to_section(pnum); - if (!preinited_vmemmap_section(ms)) - ms->section_mem_map =3D 0; - } } /* >=20 > --=20 > Cheers, >=20 > David