From nobody Tue Apr 7 22:01:44 2026 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (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 DEA362C21C3 for ; Wed, 11 Mar 2026 12:55:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773233755; cv=none; b=F20zCuL/kgEM7cmVqa8+OmOnojIqgV85WlTQidTprqwRZgEMpWD0orcxxUOrVSwh9vtvuzz/3sVJchufGcD97eXLapD+qs+BQ3Ky9Uktvqr68E/OpkTsy8zNSKhSb1oUA9uVqW/hch858syG/bqdZp9+rCFMZXSTllE4N8Z1CAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773233755; c=relaxed/simple; bh=rB9l/en//mFZLaaoe1DgyGYYfy+WslkjOBHiC8IW1Bo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fu6HaczgwNiy1O7ZvF7ciKlEdMsSil6cU2+5vKNt2KmaGH8JRD+71y/8MOdbMsDgZX7UNkQpP02wG5VZgo8WEu7Uo1k6qFPFT/jWbodSCrbw/UbDkQ/i9kdzte5b2zXZf4ft8IBo+iAivfj4MpiV16tMs8B9zJMOBLVHX6B72LU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mclapinski.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MmrGZ4jH; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mclapinski.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MmrGZ4jH" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-b94e9ac2fbcso411165666b.0 for ; Wed, 11 Mar 2026 05:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1773233752; x=1773838552; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=TW0km3bXDENe5wGoGb6FEEMiWhpRGEIF35PCM40YhbE=; b=MmrGZ4jHB1bQ41MiysVHFfM7MEWKON6ydhjxPz32VDM3rydPfH1h7KcU5C+XLwuvg7 G/DIfO2F0O+Yw5pG52kmXwpHfePsYScCYCiE9R2e3jeTgOEeeXswe+E7YCPCmA9bklAP C4HV9uOr1JPRj0n3GSjMoU44u/T8dj1jyZPAn+8Qdc9BEItjFt16+s6hXux+UEUrBWIB dejT7fW69/fIxaVtvyoTKTUpALG54pMEsp+9+sA73KjfX5x5wfQVyCDxG/yTvhkcKFLm 6mbl1akZmgPAj1jDqs3bbGlw6sVa1945Yr6rFEtrdWFZSQnO4rTnKWujJBZ/J9l4i0w0 pbAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773233752; x=1773838552; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=TW0km3bXDENe5wGoGb6FEEMiWhpRGEIF35PCM40YhbE=; b=iT3JkUy0eK6B83QMv8U91X72Gz3UORGbehq1B6uUK3GT4YzGiqdGmnHeI9QsH47aeD 40W5j+buWo4wEgbUEbDI7TBeeqk/5E8GbCXKwjd8tuKNuUh5imuCMVcBWa3aUdQQkfTB qgYYRE2JUsygkPRnopQofLxuAbIb5vNOXMhJXtmXq/epMw+HL8hCuQBZqWB4C8y/0lzi S0SiTwksRhxtI9xsVzxR1d0RKcC9vkSiNBSMIzl/6fGPZXL2SnS+jhxhW4mLS85afxUN RDFx/eLFUdgmuIpLMyh5wolhChCZct/PDTzeEZf5kVaQJXt3yRNsxADBKvmPoxTHQ3OE jN/A== X-Gm-Message-State: AOJu0Yz9OVJQTIZM/98f63rufVQmaY2xytWM7NrDC3PZQVYWfhoVOZEv V3GFbvmGzM8VDE5r3rQVJkKdkoEQjLR+PYRG5FSg522QFvbq4OeBp+GQPNxWWEvGZG9rw49f6Eg wc3CWWp5tSNbOfezt/56j1g== X-Received: from edfg22-n1.prod.google.com ([2002:a05:6402:a256:10b0:65c:72cb:9cb6]) (user=mclapinski job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:7286:b0:b88:5e32:5357 with SMTP id a640c23a62f3a-b972e5ae4e0mr140513666b.59.1773233751844; Wed, 11 Mar 2026 05:55:51 -0700 (PDT) Date: Wed, 11 Mar 2026 13:55:38 +0100 In-Reply-To: <20260311125539.4123672-1-mclapinski@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260311125539.4123672-1-mclapinski@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260311125539.4123672-2-mclapinski@google.com> Subject: [PATCH v6 1/2] kho: fix deferred init of kho scratch From: Michal Clapinski To: Evangelos Petrongonas , Pasha Tatashin , Mike Rapoport , Pratyush Yadav , Alexander Graf , Samiullah Khawaja , kexec@lists.infradead.org, linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , Michal Clapinski Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, if DEFERRED is enabled, kho_release_scratch will initialize the struct pages and set migratetype of kho scratch. Unless the whole scratch fit below first_deferred_pfn, some of that will be overwritten either by deferred_init_pages or memmap_init_reserved_pages. To fix it, I initialize kho scratch early and modify every other path to leave the scratch alone. In detail: 1. Modify deferred_init_memmap_chunk to not initialize kho scratch, since we already did that. Then, modify deferred_free_pages to not set the migratetype. Also modify reserve_bootmem_region to skip initializing kho scratch. 2. Since kho scratch is now not initialized by any other code, we have to initialize it ourselves also on cold boot. On cold boot memblock doesn't mark scratch as scratch, so we also have to modify the initialization function to not use memblock regions. Signed-off-by: Michal Clapinski --- My previous idea of marking scratch as CMA late, after deferred struct page init was done, was bad since allocations can be made before that and if they land in kho scratch, they become unpreservable. Such was the case with iommu page tables. --- include/linux/kexec_handover.h | 6 +++++ include/linux/memblock.h | 2 -- kernel/liveupdate/kexec_handover.c | 35 +++++++++++++++++++++++++++++- mm/memblock.c | 22 ------------------- mm/mm_init.c | 17 ++++++++++----- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index ac4129d1d741..612a6da6127a 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -35,6 +35,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *prese= rvation); int kho_add_subtree(const char *name, void *fdt); void kho_remove_subtree(void *fdt); int kho_retrieve_subtree(const char *name, phys_addr_t *phys); +bool pfn_is_kho_scratch(unsigned long pfn); =20 void kho_memory_init(void); =20 @@ -109,6 +110,11 @@ static inline int kho_retrieve_subtree(const char *nam= e, phys_addr_t *phys) return -EOPNOTSUPP; } =20 +static inline bool pfn_is_kho_scratch(unsigned long pfn) +{ + return false; +} + static inline void kho_memory_init(void) { } =20 static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 6ec5e9ac0699..3e217414e12d 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -614,11 +614,9 @@ static inline void memtest_report_meminfo(struct seq_f= ile *m) { } #ifdef CONFIG_MEMBLOCK_KHO_SCRATCH void memblock_set_kho_scratch_only(void); void memblock_clear_kho_scratch_only(void); -void memmap_init_kho_scratch_pages(void); #else static inline void memblock_set_kho_scratch_only(void) { } static inline void memblock_clear_kho_scratch_only(void) { } -static inline void memmap_init_kho_scratch_pages(void) {} #endif =20 #endif /* _LINUX_MEMBLOCK_H */ diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index 532f455c5d4f..09cb6660ade7 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -1327,6 +1327,23 @@ int kho_retrieve_subtree(const char *name, phys_addr= _t *phys) } EXPORT_SYMBOL_GPL(kho_retrieve_subtree); =20 +bool pfn_is_kho_scratch(unsigned long pfn) +{ + unsigned int i; + phys_addr_t scratch_start, scratch_end, phys =3D __pfn_to_phys(pfn); + + for (i =3D 0; i < kho_scratch_cnt; i++) { + scratch_start =3D kho_scratch[i].addr; + scratch_end =3D kho_scratch[i].addr + kho_scratch[i].size; + + if (scratch_start <=3D phys && phys < scratch_end) + return true; + } + + return false; +} +EXPORT_SYMBOL_GPL(pfn_is_kho_scratch); + static int __init kho_mem_retrieve(const void *fdt) { struct kho_radix_tree tree; @@ -1453,12 +1470,27 @@ static __init int kho_init(void) } fs_initcall(kho_init); =20 +static void __init kho_init_scratch_pages(void) +{ + if (!IS_ENABLED(CONFIG_DEFERRED_STRUCT_PAGE_INIT)) + return; + + for (int i =3D 0; i < kho_scratch_cnt; i++) { + unsigned long pfn =3D PFN_DOWN(kho_scratch[i].addr); + unsigned long end_pfn =3D PFN_UP(kho_scratch[i].addr + kho_scratch[i].si= ze); + int nid =3D early_pfn_to_nid(pfn); + + for (; pfn < end_pfn; pfn++) + init_deferred_page(pfn, nid); + } +} + static void __init kho_release_scratch(void) { phys_addr_t start, end; u64 i; =20 - memmap_init_kho_scratch_pages(); + kho_init_scratch_pages(); =20 /* * Mark scratch mem as CMA before we return it. That way we @@ -1487,6 +1519,7 @@ void __init kho_memory_init(void) kho_in.fdt_phys =3D 0; } else { kho_reserve_scratch(); + kho_init_scratch_pages(); } } =20 diff --git a/mm/memblock.c b/mm/memblock.c index b3ddfdec7a80..ae6a5af46bd7 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -959,28 +959,6 @@ __init void memblock_clear_kho_scratch_only(void) { kho_scratch_only =3D false; } - -__init void memmap_init_kho_scratch_pages(void) -{ - phys_addr_t start, end; - unsigned long pfn; - int nid; - u64 i; - - if (!IS_ENABLED(CONFIG_DEFERRED_STRUCT_PAGE_INIT)) - return; - - /* - * Initialize struct pages for free scratch memory. - * The struct pages for reserved scratch memory will be set up in - * reserve_bootmem_region() - */ - __for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_KHO_SCRATCH, &start, &end, &nid) { - for (pfn =3D PFN_UP(start); pfn < PFN_DOWN(end); pfn++) - init_deferred_page(pfn, nid); - } -} #endif =20 /** diff --git a/mm/mm_init.c b/mm/mm_init.c index cec7bb758bdd..969048f9b320 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -798,7 +798,8 @@ void __meminit reserve_bootmem_region(phys_addr_t start, for_each_valid_pfn(pfn, PFN_DOWN(start), PFN_UP(end)) { struct page *page =3D pfn_to_page(pfn); =20 - __init_deferred_page(pfn, nid); + if (!pfn_is_kho_scratch(pfn)) + __init_deferred_page(pfn, nid); =20 /* * no need for atomic set_bit because the struct @@ -2008,9 +2009,12 @@ static void __init deferred_free_pages(unsigned long= pfn, =20 /* Free a large naturally-aligned chunk if possible */ if (nr_pages =3D=3D MAX_ORDER_NR_PAGES && IS_MAX_ORDER_ALIGNED(pfn)) { - for (i =3D 0; i < nr_pages; i +=3D pageblock_nr_pages) + for (i =3D 0; i < nr_pages; i +=3D pageblock_nr_pages) { + if (pfn_is_kho_scratch(page_to_pfn(page + i))) + continue; init_pageblock_migratetype(page + i, MIGRATE_MOVABLE, false); + } __free_pages_core(page, MAX_PAGE_ORDER, MEMINIT_EARLY); return; } @@ -2019,7 +2023,7 @@ static void __init deferred_free_pages(unsigned long = pfn, accept_memory(PFN_PHYS(pfn), nr_pages * PAGE_SIZE); =20 for (i =3D 0; i < nr_pages; i++, page++, pfn++) { - if (pageblock_aligned(pfn)) + if (pageblock_aligned(pfn) && !pfn_is_kho_scratch(pfn)) init_pageblock_migratetype(page, MIGRATE_MOVABLE, false); __free_pages_core(page, 0, MEMINIT_EARLY); @@ -2090,9 +2094,11 @@ deferred_init_memmap_chunk(unsigned long start_pfn, = unsigned long end_pfn, unsigned long mo_pfn =3D ALIGN(spfn + 1, MAX_ORDER_NR_PAGES); unsigned long chunk_end =3D min(mo_pfn, epfn); =20 - nr_pages +=3D deferred_init_pages(zone, spfn, chunk_end); - deferred_free_pages(spfn, chunk_end - spfn); + // KHO scratch is MAX_ORDER_NR_PAGES aligned. + if (!pfn_is_kho_scratch(spfn)) + deferred_init_pages(zone, spfn, chunk_end); =20 + deferred_free_pages(spfn, chunk_end - spfn); spfn =3D chunk_end; =20 if (can_resched) @@ -2100,6 +2106,7 @@ deferred_init_memmap_chunk(unsigned long start_pfn, u= nsigned long end_pfn, else touch_nmi_watchdog(); } + nr_pages +=3D epfn - spfn; } =20 return nr_pages; --=20 2.53.0.473.g4a7958ca14-goog From nobody Tue Apr 7 22:01:44 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (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 092A72773E5 for ; Wed, 11 Mar 2026 12:55:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773233758; cv=none; b=mr3LSDrAGpthCfibNYPU10VabCdsvpJ7/4CGHrhKxBGc/UrayriISkQVS4pqzBl/2t1t2gTbyfJhbj55mV81JVBCTGP+O911hpXNq0zYe/JzvoFKVdQnL6T0J6nfoXN6iJskzYD+g4PtzulvkHMv3EIzzpWJYb059BrsOT2ULPk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773233758; c=relaxed/simple; bh=LPDF/F0/x9JGpN5I+j7Yia7+yB7dQoagUu77jOadPBw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PFdl9Txmtmu9N+i8D9ZGT/5L5J+/loGmw39JxuSD6xwFjgwfSb/MFMowz5MeNbfqIq4Z7GspH1soT8i43m42V3+F3GxIdTlgNW4BN073QwLYigvMkrIRUseFJVUUxXAZRH4u1Ffxj4WFxpehbEVAEKuNeRthHrdpQF7Or7wqPss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mclapinski.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=rMf+0VXm; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mclapinski.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rMf+0VXm" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-485375aa56eso29372995e9.1 for ; Wed, 11 Mar 2026 05:55:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1773233755; x=1773838555; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=QiNhESp4ivptJOpYZbbAOc1dWjPibReMWlebFfT5Yug=; b=rMf+0VXmytoWbaaUodanwqQ9GTmzzp7+3U5nN95dd8q5ZDFxchivahi7Eg69XP6psH KKog2rsmLeRfP1spErxZwNoNh+twZGRHtCgvpf0ubdaDQCjYhNB8qA2boMA0DASBunId IbKcgyYwUf+TOlHMQ7CH1DmHhvclo2nig6qtoVxLgC8y+vFR+o1YaGcE7NWLAifYoesR xCAv6Ppyhk0v3QlgCtYnA/liqD3p+W4H/HO3NGtadtcNoxzrl2h1nUjP7Sv8hmYLQ6xy aDaZGKr10NLbAbS9dhRzE7V94p+p0Ru1GcbafJE8Y7jMFhpJkPsijGi/cFbRG0eon+nS nWmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773233755; x=1773838555; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QiNhESp4ivptJOpYZbbAOc1dWjPibReMWlebFfT5Yug=; b=bDDli4KozbHVs9+Q8kDZEgF4hGwVTpo+MT+7ln7wLKmpM+MWkIIQqCAyOp9K4dMdKG HHo9C4zEBlletuyP+ASznpC+qc4ekqrvOdfBfvc5pj0GdEqfYng+bOM8JszozsCFWgDV ZSmv7TTqyxWnyq2Birb4Ny9t+YShFUWSGkTSQsOgFrzKFoEQgelRaJ6M2dWbDBhUh/cv FBYVpmSIm2Gepryzgr+8QfFDMkeURCb3JQHyol1tvnhe1XaKz/Vs6Xoo21jlu7ptTIvs L7U16zj7lK0s3ae7z/NGgUSx8c+n8BAW2vHG44cBILmrKFpnzOi2/MUV4BG6SCidPThQ wYpA== X-Gm-Message-State: AOJu0YwIGfPzC+GXmreiLmpzdJ+VFopCt+roNw/n2NhlGLSEMMNuLAxa YblsnGEkTjzQlCP/hzJVP9Vc6gSkZny0kOiAchWshiZwTCps/7D1s7jIyI3CjJy93W2KpKNpRO/ N79Usn7Nog0NBF8AVkH1gHA== X-Received: from wmby16.prod.google.com ([2002:a05:600c:c050:b0:480:6b05:6b9a]) (user=mclapinski job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:458e:b0:485:3ae8:2231 with SMTP id 5b1f17b1804b1-4854b11a321mr35639475e9.30.1773233755110; Wed, 11 Mar 2026 05:55:55 -0700 (PDT) Date: Wed, 11 Mar 2026 13:55:39 +0100 In-Reply-To: <20260311125539.4123672-1-mclapinski@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260311125539.4123672-1-mclapinski@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260311125539.4123672-3-mclapinski@google.com> Subject: [PATCH v6 2/2] kho: make preserved pages compatible with deferred struct page init From: Michal Clapinski To: Evangelos Petrongonas , Pasha Tatashin , Mike Rapoport , Pratyush Yadav , Alexander Graf , Samiullah Khawaja , kexec@lists.infradead.org, linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , Michal Clapinski Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Evangelos Petrongonas When CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, struct page initialization is deferred to parallel kthreads that run later in the boot process. During KHO restoration, kho_preserved_memory_reserve() writes metadata for each preserved memory region. However, if the struct page has not been initialized, this write targets uninitialized memory, potentially leading to errors like: BUG: unable to handle page fault for address: ... Fix this by introducing kho_get_preserved_page(), which ensures all struct pages in a preserved region are initialized by calling init_deferred_page() which is a no-op when the struct page is already initialized. Signed-off-by: Evangelos Petrongonas Co-developed-by: Michal Clapinski Signed-off-by: Michal Clapinski Reviewed-by: Pratyush Yadav (Google) Reviewed-by: Pasha Tatashin Reviewed-by: Mike Rapoport (Microsoft) --- I think we can't initialize those struct pages in kho_restore_page. I encountered this stack: page_zone(start_page) __pageblock_pfn_to_page set_zone_contiguous page_alloc_init_late So, at the end of page_alloc_init_late struct pages are expected to be already initialized. set_zone_contiguous() looks at the first and last struct page of each pageblock in each populated zone to figure out if the zone is contiguous. If a kho page lands on a pageblock boundary, this will lead to access of an uninitialized struct page. There is also page_ext_init that invokes pfn_to_nid, which calls page_to_nid for each section-aligned page. There might be other places that do something similar. Therefore, it's a good idea to initialize all struct pages by the end of deferred struct page init. That's why I'm resending Evangelos's patch. I also tried to implement Pratyush's idea, i.e. iterate over zones, then get node from zone. I didn't notice any performance difference even with 8GB of kho. --- kernel/liveupdate/Kconfig | 2 -- kernel/liveupdate/kexec_handover.c | 27 ++++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/kernel/liveupdate/Kconfig b/kernel/liveupdate/Kconfig index 1a8513f16ef7..c13af38ba23a 100644 --- a/kernel/liveupdate/Kconfig +++ b/kernel/liveupdate/Kconfig @@ -1,12 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only =20 menu "Live Update and Kexec HandOver" - depends on !DEFERRED_STRUCT_PAGE_INIT =20 config KEXEC_HANDOVER bool "kexec handover" depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE - depends on !DEFERRED_STRUCT_PAGE_INIT select MEMBLOCK_KHO_SCRATCH select KEXEC_FILE select LIBFDT diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index 09cb6660ade7..1f9707d11e5f 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -471,6 +471,31 @@ struct page *kho_restore_pages(phys_addr_t phys, unsig= ned long nr_pages) } EXPORT_SYMBOL_GPL(kho_restore_pages); =20 +/* + * With CONFIG_DEFERRED_STRUCT_PAGE_INIT, struct pages in higher memory re= gions + * may not be initialized yet at the time KHO deserializes preserved memor= y. + * KHO uses the struct page to store metadata and a later initialization w= ould + * overwrite it. + * Ensure all the struct pages in the preservation are + * initialized. kho_preserved_memory_reserve() marks the reservation as no= init + * to make sure they don't get re-initialized later. + */ +static struct page *__init kho_get_preserved_page(phys_addr_t phys, + unsigned int order) +{ + unsigned long pfn =3D PHYS_PFN(phys); + int nid; + + if (!IS_ENABLED(CONFIG_DEFERRED_STRUCT_PAGE_INIT)) + return pfn_to_page(pfn); + + nid =3D early_pfn_to_nid(pfn); + for (unsigned long i =3D 0; i < (1UL << order); i++) + init_deferred_page(pfn + i, nid); + + return pfn_to_page(pfn); +} + static int __init kho_preserved_memory_reserve(phys_addr_t phys, unsigned int order) { @@ -479,7 +504,7 @@ static int __init kho_preserved_memory_reserve(phys_add= r_t phys, u64 sz; =20 sz =3D 1 << (order + PAGE_SHIFT); - page =3D phys_to_page(phys); + page =3D kho_get_preserved_page(phys, order); =20 /* Reserve the memory preserved in KHO in memblock */ memblock_reserve(phys, sz); --=20 2.53.0.473.g4a7958ca14-goog