From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D72818DB1F for ; Fri, 24 Apr 2026 01:05:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776992741; cv=none; b=R136hwwsPXRlJAvCQHol4XLBsiydoY0B3Kvjggsbcl6wsc3bkMRo1442mbGBMur8wT8JzulDfJ5peIywuufv3jCNPDafmFrCLeglm6kYdm0EuNmmnA1t+wW9qPMUa/RE39A956AQxMDIkhJEe8agquBK2DhorxLoIJwdnsNJO5I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776992741; c=relaxed/simple; bh=pw1Rpw6FxrLZk1C1H+tE9maYINi04gZxTa7whLKlXQQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=mLd3V0EqdvbuAK/RC2mDUDV+FZOC4drm0x+C8TfgXkiWozsdc4kTtD1JNgsDBTltntgxH3ZGYQ8pMuTj4+jdq4IO7e04JGiwcWBc+9+xEok3u+wlZ2oftCa/UaTZLJ9De0aOApexLZQxsVJNa8yzPl216d0T9MuCS0hU0L/7CFo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Xz6PT3oa; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xz6PT3oa" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-b9382e59c0eso199754866b.0 for ; Thu, 23 Apr 2026 18:05:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776992738; x=1777597538; darn=vger.kernel.org; h=user-agent:in-reply-to:content-disposition:mime-version:references :reply-to:message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=92hmxtrw01jgdnML3HNZxYWHad+ML6IkMirm0dl8+MU=; b=Xz6PT3oa/7H9DzDJpsVj9Zq8ML9hYhYxzoYXzTikWKjnAa4QL8zNOveqTw8Vf0H+0s k1V9tyyES/5rmUPkzqQ8bddSiv6j7dSoHSm4+Y7WkMMmyAsTJTy/JFgtcCixMzzo7Be0 RlJDPa4YFrO+okwk9v6zbG2UbpzlwQBVQ/jxXeSYfQlaPedOeSV9POksZeKnSDUKcrnJ xGtSCy4wZ+qSXiuNM+1sPBeqC/139lCEosHgDXNaZsbNYu7XfnROfquqRLwmf+ytlkWS GNFcV9CUQNzQ/iY9IPLc712BmfepDaPRSEmgz7sm8zPe4Iy7ElGF9RPwdxsYAVjGjQPs Cz9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776992738; x=1777597538; h=user-agent:in-reply-to:content-disposition:mime-version:references :reply-to:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=92hmxtrw01jgdnML3HNZxYWHad+ML6IkMirm0dl8+MU=; b=loLo5ajcnIn0mJwtA7I8ll2ZPDScMUnyaTigHXdI06TcGV18a+oP7KIcdTDJs74KzV 8dtKl6O21srtd9nQncKBdRTZKhjibOEBfVT9QdlJ2n9r25o9ErRs4LwOboL49xQGDoMT UYu2nGgQmrl8JN5C4ZOteyM9j0gV97BhutDdEzdNd0+hV7waWRIptQnFeHd5pQNfAhQ6 NqdRm2q7UucjXgF5HH+WBklu01DpZGQYJkYeEE6r3QxppnjSgpZxL6c54HohHz6ns45e kAWf//Uoui7QFJfcXX75q1Z7HMMrsszxwsQ3VcKLM65tsYhgELEwJsjD4gJmShXmddGW jw1A== X-Forwarded-Encrypted: i=1; AFNElJ9COmZnBiGvAFu9JhJEGZcF0dqRMEaWkRi5veu0o+MRgM60sfXVDfZu5QTAQs57oW0Qw/fAcupMSwRQa9w=@vger.kernel.org X-Gm-Message-State: AOJu0Yz3L6lpj/qSW1tgDonBlzrCANyVWdrXNbKiPDIlBnMU54Cky4sn SxfkmEa+iTwZbFIuLBLimk+EzLcpxe0Syf4PBkqBgaB98iYlquXlJMXU X-Gm-Gg: AeBDievG24MGXhmSdRrFEOG84GNzkrdvjYgEpMzPsQYnr2TJ/zAM8OOclgXHlqnU1Cl Ak8jClbWceCMWnDimRvWhQXIHir3pzw8YZf2wZi7YHOpA3KDjHN5ByHUihfaMWaDJWHqbbVyJfH 2PpDk3IvMgq6ThKxJ4P2aGr7GABFp3zojrnWkOpvqVR0ph44NfbjyCnHrwunyPi1YVkOQlsxtDh OawvLW5N+3bLFAs/2JeNUx794NAs+MDZpj47MMmLGjcIAzQIG3i0tCLn9qLPHgwZSa+j2Nx16Yr WT5gIOKVI1t+aFgAS5ozw3oYs1a8bQyZBHMBoJSenhxK5XEiUtHOfqUI0PCQryA4GqzKTUSnzRz FDdo1JxBez96tHAa93Z/rbqyn7gtPABKILVY0qBzI41tw8iNIQ6zaOS+F3k05qkVNwv21pr0Kb4 xl5BIuPhpLnnSjmGROsFagazVS3b3NAP4A X-Received: by 2002:a17:907:a60b:b0:ba0:fd75:9c58 with SMTP id a640c23a62f3a-ba41b3e1284mr1347700866b.32.1776992737552; Thu, 23 Apr 2026 18:05:37 -0700 (PDT) Received: from localhost ([185.92.221.13]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba45553e502sm709993966b.61.2026.04.23.18.05.35 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 23 Apr 2026 18:05:36 -0700 (PDT) Date: Fri, 24 Apr 2026 01:05:35 +0000 From: Wei Yang To: "Liu, Yuan1" Cc: Wei Yang , David Hildenbrand , Oscar Salvador , Mike Rapoport , "linux-mm@kvack.org" , "Hu, Yong" , "Zou, Nanhai" , Tim Chen , "Zhuo, Qiuxu" , "Chen, Yu C" , "Deng, Pan" , "Li, Tianyou" , Chen Zhang , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH v4 1/2] mm: move overlap memory map init check to memmap_init() Message-ID: <20260424010535.54sh5z6nkqt3j6du@master> Reply-To: Wei Yang References: <20260421125508.2317429-1-yuan1.liu@intel.com> <20260421125508.2317429-2-yuan1.liu@intel.com> <20260422011126.thu67icgj5qfbecj@master> <20260422032646.vtkdoliudlxgtpv3@master> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170113 (1.7.2) On Wed, Apr 22, 2026 at 09:28:52AM +0000, Liu, Yuan1 wrote: >> -----Original Message----- >> From: Wei Yang >> Sent: Wednesday, April 22, 2026 11:27 AM >> To: Wei Yang >> Cc: Liu, Yuan1 ; David Hildenbrand >> ; Oscar Salvador ; Mike Rapoport >> ; linux-mm@kvack.org; Hu, Yong ; Zou, >> Nanhai ; Tim Chen ; >> Zhuo, Qiuxu ; Chen, Yu C ; >> Deng, Pan ; Li, Tianyou ; Chen >> Zhang ; linux-kernel@vger.kernel.org >> Subject: Re: [PATCH v4 1/2] mm: move overlap memory map init check to >> memmap_init() >> >> On Wed, Apr 22, 2026 at 01:11:26AM +0000, Wei Yang wrote: >> >On Tue, Apr 21, 2026 at 08:55:07AM -0400, Yuan Liu wrote: >> >>Move the overlap memmap init check from memmap_init_range() into >> >>memmap_init(). >> >> >> >>When mirrored kernelcore is enabled, avoid memory map initialization >> >>for overlap regions. There are two cases that may overlap: a mirror >> >>memory region assigned to movable zone, or a non-mirror memory region >> >>assigned to a non-movable zone but falling within the movable zone >> >>range. >> >> >> >>Signed-off-by: Yuan Liu >> >>--- >> >> mm/mm_init.c | 37 +++++++++++++------------------------ >> >> 1 file changed, 13 insertions(+), 24 deletions(-) >> >> >> >>diff --git a/mm/mm_init.c b/mm/mm_init.c >> >>index df34797691bd..2b5233060504 100644 >> >>--- a/mm/mm_init.c >> >>+++ b/mm/mm_init.c >> >>@@ -797,28 +797,6 @@ void __meminit reserve_bootmem_region(phys_addr_t >> start, >> >> } >> >> } >> >> >> >>-/* If zone is ZONE_MOVABLE but memory is mirrored, it is an overlapped >> init */ >> >>-static bool __meminit >> >>-overlap_memmap_init(unsigned long zone, unsigned long *pfn) >> >>-{ >> >>- static struct memblock_region *r; >> >>- >> >>- if (mirrored_kernelcore && zone == ZONE_MOVABLE) { >> >>- if (!r || *pfn >= memblock_region_memory_end_pfn(r)) { >> >>- for_each_mem_region(r) { >> >>- if (*pfn < memblock_region_memory_end_pfn(r)) >> >>- break; >> >>- } >> >>- } >> >>- if (*pfn >= memblock_region_memory_base_pfn(r) && >> >>- memblock_is_mirror(r)) { >> >>- *pfn = memblock_region_memory_end_pfn(r); >> >>- return true; >> >>- } >> >>- } >> >>- return false; >> >>-} >> >>- >> >> /* >> >> * Only struct pages that correspond to ranges defined by >> memblock.memory >> >> * are zeroed and initialized by going through __init_single_page() >> during >> >>@@ -905,8 +883,6 @@ void __meminit memmap_init_range(unsigned long size, >> int nid, unsigned long zone >> >> * function. They do not exist on hotplugged memory. >> >> */ >> >> if (context == MEMINIT_EARLY) { >> >>- if (overlap_memmap_init(zone, &pfn)) >> >>- continue; >> >> if (defer_init(nid, pfn, zone_end_pfn)) { >> >> deferred_struct_pages = true; >> >> break; >> >>@@ -971,6 +947,7 @@ static void __init memmap_init(void) >> >> >> >> for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) >> { >> >> struct pglist_data *node = NODE_DATA(nid); >> >>+ struct memblock_region *r = &memblock.memory.regions[i]; >> >> >> >> for (j = 0; j < MAX_NR_ZONES; j++) { >> >> struct zone *zone = node->node_zones + j; >> >>@@ -978,6 +955,18 @@ static void __init memmap_init(void) >> >> if (!populated_zone(zone)) >> >> continue; >> >> >> >>+ if (mirrored_kernelcore) { >> >>+ const bool is_mirror = memblock_is_mirror(r); >> >>+ const bool is_movable_zone = (j == ZONE_MOVABLE); >> >>+ >> >>+ if (is_mirror && is_movable_zone) >> >>+ continue; >> >>+ >> >>+ if (!is_mirror && !is_movable_zone && >> >>+ start_pfn >= zone_movable_pfn[nid]) >> >>+ continue; >> > >> >IIUC, when mirrored_kernelcore is set but !memblock_has_mirror() or >> >is_kdump_kernel(), zone_movable_pfn[nid] is kept to be 0. >> > >> >This means it will skip all memory regions. >> > >> >> Did some tests. When mirrored_kernelcore && !memblock_has_mirror(), which >> means there is no is_mirror memblock. This will leave >> zone_movable_pfn[nid] 0. >> >> So for all memory regions, the above logic will skip them. >> >> Adjust the code as below, my local test could pass and kernel bootup as >> expected. >> >> From 6351ac79a17edbfd830510fba2959ddc47b17258 Mon Sep 17 00:00:00 2001 >> From: Wei Yang >> Date: Wed, 22 Apr 2026 09:13:24 +0800 >> Subject: [PATCH] skip overlap region higher level >> >> --- >> mm/mm_init.c | 29 ++++++++++++++++++++++------- >> 1 file changed, 22 insertions(+), 7 deletions(-) >> >> diff --git a/mm/mm_init.c b/mm/mm_init.c >> index 79f93f2a90cf..7a85ba58e87f 100644 >> --- a/mm/mm_init.c >> +++ b/mm/mm_init.c >> @@ -916,8 +916,8 @@ void __meminit memmap_init_range(unsigned long size, >> int nid, unsigned long zone >> * function. They do not exist on hotplugged memory. >> */ >> if (context == MEMINIT_EARLY) { >> - if (overlap_memmap_init(zone, &pfn)) >> - continue; >> + // if (overlap_memmap_init(zone, &pfn)) >> + // continue; >> if (defer_init(nid, pfn, zone_end_pfn)) { >> deferred_struct_pages = true; >> break; >> @@ -974,6 +974,17 @@ static void __init memmap_init_zone_range(struct zone >> *zone, >> *hole_pfn = end_pfn; >> } >> >> +static bool __init region_overlapped(struct memblock_region *rgn, >> unsigned long zone_type) >> +{ >> + if (zone_type == ZONE_MOVABLE && memblock_is_mirror(rgn)) >> + return true; >> + >> + if (zone_type == ZONE_NORMAL && !memblock_is_mirror(rgn)) >> + return true; >> + >> + return false; >> +} >> + >> static void __init memmap_init(void) >> { >> unsigned long start_pfn, end_pfn; >> @@ -985,10 +996,15 @@ static void __init memmap_init(void) >> >> for (j = 0; j < MAX_NR_ZONES; j++) { >> struct zone *zone = node->node_zones + j; >> + struct memblock_region *r = &memblock.memory.regions[i]; >> >> if (!populated_zone(zone)) >> continue; >> >> + if (mirrored_kernelcore && zone_movable_pfn[nid] && >> + region_overlapped(r, j)) >> + continue; >> + >> memmap_init_zone_range(zone, start_pfn, end_pfn, >> &hole_pfn); >> zone_id = j; >> @@ -1257,13 +1273,12 @@ static unsigned long __init >> zone_absent_pages_in_node(int nid, >> end_pfn = clamp(memblock_region_memory_end_pfn(r), >> zone_start_pfn, zone_end_pfn); >> >> - if (zone_type == ZONE_MOVABLE && >> - memblock_is_mirror(r)) >> - nr_absent += end_pfn - start_pfn; >> + if (start_pfn == end_pfn) >> + continue; >> >> - if (zone_type == ZONE_NORMAL && >> - !memblock_is_mirror(r)) >> + if (region_overlapped(r, zone_type)) >> nr_absent += end_pfn - start_pfn; >> + >> } >> } > >Hi Wei Yang > >I ran some tests based on this patch and didn't observe any issues. >Thanks for the patch. > You are welcome. Well, maybe we need to do something more. Let me explain what I see. My assumption of the position of mirror memory is: When there is mirror memory in system, all memory in low zone should be mirror memory. Non-Mirror memory only could be in the range of ZONE_NORMAL. And in the range of ZONE_NORMAL * there could be no mirror memory * the mirror memory could be at the head or middle in ZONE_NORMAL Take my test machine as an example, MEMBLOCK configuration: memory size = 0x000000017ff7dc00 reserved size = 0x0000000005a9a9c2 memory.cnt = 0x3 memory[0x0] [0x0000000000001000-0x000000000009efff], 0x000000000009e000 bytes on node 0 flags: 0x0 memory[0x1] [0x0000000000100000-0x00000000bffdefff], 0x00000000bfedf000 bytes on node 0 flags: 0x0 memory[0x2] [0x0000000100000000-0x00000001bfffffff], 0x00000000c0000000 bytes on node 1 flags: 0x0 The first two memblock region span ZONE_DMA and ZONE_DMA32. The third one span ZONE_NORMAL.(When kernelcore is not specified). So I did test with below code change: @@ -147,6 +148,14 @@ static int __init numa_register_nodes(void) } /* Dump memblock with node info and return. */ + + /* Mark mirror by hand */ + for_each_mem_region(r) { + if (i++ < 2) + memblock_mark_mirror(r->base, r->size); + } + This mark the first two memblock region as mirror. And then use memblock_mark_mirror(0x100000000, 0x40000000); or memblock_mark_mirror(0x140000000, 0x40000000); To mark the head 1G or second 1G as mirror in the 3rd memblock region to mimic the overlap case. So I manually create 3 cases: A: all ZONE_NORMAL is non-mirror memory[0x0] [0x0000000000001000-0x000000000009efff], node 0 flags: 0x2 mirror memory[0x1] [0x0000000000100000-0x00000000bffdefff], node 0 flags: 0x2 mirror memory[0x2] [0x0000000100000000-0x00000001bfffffff], node 1 flags: 0x0 non-mirror B: head 1G of ZONE_NORMAL is mirror memory[0x0] [0x0000000000001000-0x000000000009efff], node 0 flags: 0x2 mirror memory[0x1] [0x0000000000100000-0x00000000bffdefff], node 0 flags: 0x2 mirror memory[0x2] [0x0000000100000000-0x000000013fffffff], node 1 flags: 0x2 mirror memory[0x3] [0x0000000140000000-0x00000001bfffffff], node 1 flags: 0x0 non-mirror C: second 1G of ZONE_NORMAL is mirror memory[0x0] [0x0000000000001000-0x000000000009efff], node 0 flags: 0x2 mirror memory[0x1] [0x0000000000100000-0x00000000bffdefff], node 0 flags: 0x2 mirror memory[0x2] [0x0000000100000000-0x000000013fffffff], node 1 flags: 0x0 non-mirror memory[0x3] [0x0000000140000000-0x000000017fffffff], node 1 flags: 0x2 mirror memory[0x4] [0x0000000180000000-0x00000001bfffffff], node 1 flags: 0x0 non-mirror The change I proposed works fine for A/B, but for C pages in [0x140000000-0x17fffffff] is miss placed. Node 1, zone Normal spanned 0 present 0 <-- missing managed 0 Node 1, zone Movable spanned 786432 present 524288 managed 773552 <-- but put in here The reason is in adjust_zone_range_for_zone_movable(), ZONE_NORMAL is truncated, since zone_movable_pfn[nid] equals to ZONE_NORMAL's start. So this range is skipped and then by "accident" it is initialized by init_unavailable_range() to ZONE_MOVABLE. And then it is freed to ZONE_MOVABLE in __free_pages_core(). After removing this truncation, the zone stats looks good. Node 1, zone Normal spanned 786432 present 262144 managed 249310 Node 1, zone Movable spanned 786432 present 524288 managed 517223 @@ -1204,10 +1204,7 @@ static void __init adjust_zone_range_for_zone_movable(int nid, *zone_start_pfn < zone_movable_pfn[nid] && *zone_end_pfn > zone_movable_pfn[nid]) { *zone_end_pfn = zone_movable_pfn[nid]; - - /* Check if this whole range is within ZONE_MOVABLE */ - } else if (*zone_start_pfn >= zone_movable_pfn[nid]) - *zone_start_pfn = *zone_end_pfn; + } } } All above analysis is based on my assumption on possible mirror memory position in system. If my assumption of mirror memory is not true, this may not be true. -- Wei Yang Help you, Help me