From nobody Thu Apr 2 14:14:43 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 B5BAF3E51CF for ; Tue, 17 Mar 2026 14:15:45 +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=1773756947; cv=none; b=e3L10RwBPaTPazlxBBFfWPXYHN0rA6vxEW7U0OI6MPCRDO7x/AlGyTIYvJ/IB6+9hc5+1LxWil/8IW7bakjzkGWMOV2tXDwRKKZ2mWuwZSg1yzGqtoC6Hn6IW4+sfw8intRIl4kcTwwx3T8jKqLzqhy1tQNqiWxC14fRyr/apxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773756947; c=relaxed/simple; bh=LOrfLnP3RZxCRYFPh7LcX+0C3qA1PGoymsVNK00PspE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XNZfQiXK8D89zWtShRH6hnkpCrPn84f7c89G8GvYcYb/XEz+jNlkbZJEBetz3mzqxHxlemE3ZjY7QGzwZ6zkGwd72T3Wk+ShZ+p4aUXTJ2Ex0d+pcDYQtvPnHUMSV+Bb4hSoJxZ7JIpoIipKvPeaBrTUjDMGoUQC/+LWGuTppa4= 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=aK74jQuO; 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="aK74jQuO" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-485350666bfso46293565e9.3 for ; Tue, 17 Mar 2026 07:15:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1773756944; x=1774361744; 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=6pQdqVuW3s3IY2V2/GcIHf4+cwJRcBc6iC91+pnO9/s=; b=aK74jQuOKNaZi954mU/EZtTwO79pyq7J/ehEEWd7NL3Z1BdyoajwHriku1SdIz/LeR 2BemxXa5q74FjTaGxIFp4E6FfECmbuf5MBohByzXANrWk7yJhz4Ru3p9TBV/NrHGapxI 4u/BCu68qGL1oYjoQqA9bK1+PEWhAwRJkX5Bx43O6SgFeiO570zlmXCWGjGS5urRgVy9 mBcMwZbg2rGnugb0M3J3c5IRTPx7NWwspgAHoHj8v2c9HnFz96/pU9HNiGV4Ot2c2BU3 lBvsbDskfkKw23mlOC3En/S7Byh6hNc9Dji0a3TQkx6Fe/88Etc/uI4OwnBaHNhz7u4+ OGhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773756944; x=1774361744; 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=6pQdqVuW3s3IY2V2/GcIHf4+cwJRcBc6iC91+pnO9/s=; b=sk4zGD4zFaO71OLw98RDJyq6YiaSUU+VtYn7j9a2sabicLJtX/92Xckl6FVW6/jXZm 8W86rsMNzKvF5VB8g0RyeGTqX9EUtqQCub35BQ4DFlUyCNT1Gn14ReNhDU2ySycmBEaS 46GH8uTi7+7CDbe2GVk700emmye5BJ+NqcwVn8UtRf1mwALqApKRb5MmyHZtdoZ6eJoB qUbCrbgufdSQfQFEuLFIovquNoJh+p6lRq8w6EaF8QpKs42REyJlqC8nPgW0KROw6QLr rzGuQ6nq1+TMq2yaahcdMfCVRNMhY1QKMSyZtdQLw/WdRyPiDoQRYb72FyIeYdPJPEKl s5iw== X-Gm-Message-State: AOJu0YzCzd+yVLPiGg/E5vWd7sC/GvKqXGiN620OGeBdkT2+7iiotAJu DBbqeKRuhFjisnQuGvNxQwWhNcQfpPLhF76QqID/zfdjcDH/lN4ivqXoaX7BvO5GREAOyNW+e41 P/ZCUc/nv6K/PJEkJ2xUWRA== X-Received: from wmz7.prod.google.com ([2002:a05:600c:6b67:b0:485:3aa2:da59]) (user=mclapinski job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4583:b0:485:3f17:410 with SMTP id 5b1f17b1804b1-485566fd031mr299341025e9.16.1773756943916; Tue, 17 Mar 2026 07:15:43 -0700 (PDT) Date: Tue, 17 Mar 2026 15:15:32 +0100 In-Reply-To: <20260317141534.815634-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: <20260317141534.815634-1-mclapinski@google.com> X-Mailer: git-send-email 2.53.0.851.ga537e3e6e9-goog Message-ID: <20260317141534.815634-2-mclapinski@google.com> Subject: [PATCH v7 1/3] kho: make kho_scratch_overlap usable outside debugging 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" Also return false if kho_scratch is NULL. Signed-off-by: Michal Clapinski --- include/linux/kexec_handover.h | 6 +++++ kernel/liveupdate/Makefile | 1 - kernel/liveupdate/kexec_handover.c | 28 ++++++++++++++++++--- kernel/liveupdate/kexec_handover_debug.c | 25 ------------------ kernel/liveupdate/kexec_handover_internal.h | 7 ++++-- 5 files changed, 35 insertions(+), 32 deletions(-) delete mode 100644 kernel/liveupdate/kexec_handover_debug.c diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index ac4129d1d741..6a0e572c3adc 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 kho_scratch_overlap(phys_addr_t phys, size_t size); =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 kho_scratch_overlap(phys_addr_t phys, size_t size) +{ + 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/kernel/liveupdate/Makefile b/kernel/liveupdate/Makefile index d2f779cbe279..dc352839ccf0 100644 --- a/kernel/liveupdate/Makefile +++ b/kernel/liveupdate/Makefile @@ -7,7 +7,6 @@ luo-y :=3D \ luo_session.o =20 obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o -obj-$(CONFIG_KEXEC_HANDOVER_DEBUG) +=3D kexec_handover_debug.o obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debugfs.o =20 obj-$(CONFIG_LIVEUPDATE) +=3D luo.o diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index 532f455c5d4f..c9b982372d6e 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -820,7 +820,8 @@ int kho_preserve_folio(struct folio *folio) const unsigned long pfn =3D folio_pfn(folio); const unsigned int order =3D folio_order(folio); =20 - if (WARN_ON(kho_scratch_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order))) + if (WARN_ON(kho_scratch_overlap_debug(pfn << PAGE_SHIFT, + PAGE_SIZE << order))) return -EINVAL; =20 return kho_radix_add_page(tree, pfn, order); @@ -864,10 +865,9 @@ int kho_preserve_pages(struct page *page, unsigned lon= g nr_pages) unsigned long failed_pfn =3D 0; int err =3D 0; =20 - if (WARN_ON(kho_scratch_overlap(start_pfn << PAGE_SHIFT, - nr_pages << PAGE_SHIFT))) { + if (WARN_ON(kho_scratch_overlap_debug(start_pfn << PAGE_SHIFT, + nr_pages << PAGE_SHIFT))) return -EINVAL; - } =20 while (pfn < end_pfn) { unsigned int order =3D @@ -1327,6 +1327,26 @@ int kho_retrieve_subtree(const char *name, phys_addr= _t *phys) } EXPORT_SYMBOL_GPL(kho_retrieve_subtree); =20 +bool kho_scratch_overlap(phys_addr_t phys, size_t size) +{ + phys_addr_t scratch_start, scratch_end; + unsigned int i; + + if (!kho_scratch) + return false; + + 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 (phys < scratch_end && (phys + size) > scratch_start) + return true; + } + + return false; +} +EXPORT_SYMBOL_GPL(kho_scratch_overlap); + static int __init kho_mem_retrieve(const void *fdt) { struct kho_radix_tree tree; diff --git a/kernel/liveupdate/kexec_handover_debug.c b/kernel/liveupdate/k= exec_handover_debug.c deleted file mode 100644 index 6efb696f5426..000000000000 --- a/kernel/liveupdate/kexec_handover_debug.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * kexec_handover_debug.c - kexec handover optional debug functionality - * Copyright (C) 2025 Google LLC, Pasha Tatashin - */ - -#define pr_fmt(fmt) "KHO: " fmt - -#include "kexec_handover_internal.h" - -bool kho_scratch_overlap(phys_addr_t phys, size_t size) -{ - phys_addr_t scratch_start, scratch_end; - unsigned int i; - - 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 (phys < scratch_end && (phys + size) > scratch_start) - return true; - } - - return false; -} diff --git a/kernel/liveupdate/kexec_handover_internal.h b/kernel/liveupdat= e/kexec_handover_internal.h index 9a832a35254c..804d6a1209b8 100644 --- a/kernel/liveupdate/kexec_handover_internal.h +++ b/kernel/liveupdate/kexec_handover_internal.h @@ -41,9 +41,12 @@ static inline void kho_debugfs_fdt_remove(struct kho_deb= ugfs *dbg, #endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */ =20 #ifdef CONFIG_KEXEC_HANDOVER_DEBUG -bool kho_scratch_overlap(phys_addr_t phys, size_t size); +static inline bool kho_scratch_overlap_debug(phys_addr_t phys, size_t size) +{ + return kho_scratch_overlap(phys, size); +} #else -static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size) +static inline bool kho_scratch_overlap_debug(phys_addr_t phys, size_t size) { return false; } --=20 2.53.0.851.ga537e3e6e9-goog From nobody Thu Apr 2 14:14:43 2026 Received: from mail-ed1-f74.google.com (mail-ed1-f74.google.com [209.85.208.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 E53B73E5570 for ; Tue, 17 Mar 2026 14:15:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773756950; cv=none; b=do+bYT385jN67kOl6Ojzuke2igpTt2joGxav0rYstZa7XrB4TFyEQ2dzVEdXUO4yW2thbQhMdj8drKoQWZx21HcEeJC73FHiFS2Qw+pfl7hLfN+qRPVtkN7oB80gGqyqNxqQg9aV+JB/5UjfaPp9U9xxzmebu493K8CGsnaX3bA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773756950; c=relaxed/simple; bh=aAjuW+iInrYyj1G1O1LeqTq5lJXMgon95IsJaRIr93s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=maunhliC64cWx6fItfhZEW7u4TjMi1GAZLjI8TvdJycYYEHK/i+n7/1CWc20iGwxgCBRG2wXpHCz7ngT+k5FBeKx/tCecDMXe4+hcAiOzU8opyh5xwDQj7McU5Nh9nOiSI9zLaRmUxAgNLlbNktNmGA71t7LqMhb9M5JC5PoIbw= 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=o5BPwSZS; arc=none smtp.client-ip=209.85.208.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="o5BPwSZS" Received: by mail-ed1-f74.google.com with SMTP id 4fb4d7f45d1cf-666d0b4acfcso2177134a12.0 for ; Tue, 17 Mar 2026 07:15:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1773756947; x=1774361747; 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=ENui0Js8tkhd80bmpMrXzJoFIzd5GZKUFokCk0GUoAI=; b=o5BPwSZSzcoEoxPOqD6hgFw0fhaEG6wR989MkYrwXXHd2pc1erR16yXA3KVeLHEvuR v/HFlS0z7bcbVweGJSdnIFOWfn3hmxjj8hExOFxf3y9f12NzFRgdgLxOTdoYrOh3QEJg V88yhJsKkN67RHjMg05cJ/zsyh9T1BRhHKqhMukjz1cQYaoZOQCQNvcBBYN4VQwKDI3m VaHPSsvlqPOnUO4Q5hmcixLiWDAmSKZPLCAkae1GE9jwkYgdKbIsG/MuSclqtWEVW6do kkuwckzE6ZUIzGtPiLXzYEKIQBRkG0SKEdDS1nyCZMETfIWrPZBwYWmVs0qHWyi9nK9/ jt5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773756947; x=1774361747; 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=ENui0Js8tkhd80bmpMrXzJoFIzd5GZKUFokCk0GUoAI=; b=fdJ6OKPSBTaAUlKs5ewPF0jGYdLjzUuzP1gd6s38t+FAo80mdTKUDVgoeUWQKQtdb8 J0OYnllCPUOlqWu1+sZMHavs/8ppY2ItuV2SxaqYgrYG3MBoaQfBOjzehR71PCCNLHWM 6VsYNc12gbAjVHOz70ACcfvpCGIE5nQQAlAmTCj7+4tKvMZ6rMUfuO71OZMa4jo+A/Si X7j5gK2JF8HoBQxFye9kpphe6leXKixtdjJdE3lEGTxI9jPLlmYrqkTKpYa1hAyPGiGH s+wsLAPVrfzGH6E8a9Dc9/LAkVS7hPA+Z8nh5Bkp1jVsKHJgghUX69e0x6y99cTMwLaM WVIA== X-Gm-Message-State: AOJu0Yx9iu2yIcUGctAfCdDT+FSm+4JPFURVJ6JwGIK8r3wjAySvj7D7 JOBYfnsmXJP5w5Z7SV6dNal+WNz+/WOdaIr8AJY+xV/9asSp+7xmSSvMs/AF+mZI1O7zLjPVOgo 7uF0VYpnayM/YY3gF0Np1cw== X-Received: from edew21-n1.prod.google.com ([2002:a05:6402:a215:10b0:662:4e97:3bc9]) (user=mclapinski job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:26c5:b0:667:5318:2bc9 with SMTP id 4fb4d7f45d1cf-66753182f33mr1449370a12.15.1773756947028; Tue, 17 Mar 2026 07:15:47 -0700 (PDT) Date: Tue, 17 Mar 2026 15:15:33 +0100 In-Reply-To: <20260317141534.815634-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: <20260317141534.815634-1-mclapinski@google.com> X-Mailer: git-send-email 2.53.0.851.ga537e3e6e9-goog Message-ID: <20260317141534.815634-3-mclapinski@google.com> Subject: [PATCH v7 2/3] 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 modified kho_release_scratch to only set the migratetype on already initialized pages. Then, modified init_pageblock_migratetype to set the migratetype to CMA if the page is located inside scratch. Signed-off-by: Michal Clapinski --- include/linux/memblock.h | 2 -- kernel/liveupdate/kexec_handover.c | 10 ++++++---- mm/memblock.c | 22 ---------------------- mm/page_alloc.c | 7 +++++++ 4 files changed, 13 insertions(+), 28 deletions(-) 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 c9b982372d6e..e511a50fab9c 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -1477,8 +1477,7 @@ static void __init kho_release_scratch(void) { phys_addr_t start, end; u64 i; - - memmap_init_kho_scratch_pages(); + int nid; =20 /* * Mark scratch mem as CMA before we return it. That way we @@ -1486,10 +1485,13 @@ static void __init kho_release_scratch(void) * we can reuse it as scratch memory again later. */ __for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_KHO_SCRATCH, &start, &end, NULL) { + MEMBLOCK_KHO_SCRATCH, &start, &end, &nid) { ulong start_pfn =3D pageblock_start_pfn(PFN_DOWN(start)); ulong end_pfn =3D pageblock_align(PFN_UP(end)); ulong pfn; +#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT + end_pfn =3D min(end_pfn, NODE_DATA(nid)->first_deferred_pfn); +#endif =20 for (pfn =3D start_pfn; pfn < end_pfn; pfn +=3D pageblock_nr_pages) init_pageblock_migratetype(pfn_to_page(pfn), @@ -1500,8 +1502,8 @@ static void __init kho_release_scratch(void) void __init kho_memory_init(void) { if (kho_in.scratch_phys) { - kho_scratch =3D phys_to_virt(kho_in.scratch_phys); kho_release_scratch(); + kho_scratch =3D phys_to_virt(kho_in.scratch_phys); =20 if (kho_mem_retrieve(kho_get_fdt())) kho_in.fdt_phys =3D 0; 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/page_alloc.c b/mm/page_alloc.c index ee81f5c67c18..5ca078dde61d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "internal.h" #include "shuffle.h" @@ -549,6 +550,12 @@ void __meminit init_pageblock_migratetype(struct page = *page, migratetype < MIGRATE_PCPTYPES)) migratetype =3D MIGRATE_UNMOVABLE; =20 + /* + * Mark KHO scratch as CMA so no unmovable allocations are made there. + */ + if (unlikely(kho_scratch_overlap(page_to_phys(page), PAGE_SIZE))) + migratetype =3D MIGRATE_CMA; + flags =3D migratetype; =20 #ifdef CONFIG_MEMORY_ISOLATION --=20 2.53.0.851.ga537e3e6e9-goog From nobody Thu Apr 2 14:14:43 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 2EBA43E7177 for ; Tue, 17 Mar 2026 14:15:52 +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=1773756953; cv=none; b=BLoLtGe+a23qRJWUSQJbgJ+Dq33HCM1QAm6dn4ED9g3zOJG1cuw9gqDiMM0S4Asma1KOlynmyUef/3q38Ms9gPMqKwD6qnGry9o8kk0d/4ozhCZNLajdP5gqa/Tdazn1TBMgO52cuayXW7vitoxjzw0uIw4GL7kkVlhL0hZ+4cA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773756953; c=relaxed/simple; bh=Iz88SWLxpj7z1SorA7PAVpSrur17/8yfRfM/80b4T3I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=W7QQZ2+1U0xgYpHMmC5FybraPO5+9P3Zbd9Eh3yB1oe00xZm7QIOa9bT8lMZgJ1R2Vv+oBjFh3TXsIu2qriWza7gQTN3JOK2XZSVaI4sNwgM1VLUav9QUb59T8X9RIpEQCyFDueh8CuGMqXfe59KuPcC9/y5PBoCCB3IrGDtBqI= 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=KTeUWEvr; 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="KTeUWEvr" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso76641225e9.1 for ; Tue, 17 Mar 2026 07:15:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1773756950; x=1774361750; 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=20jDT7vbb/pcwg3RWwDlyXHU14Ovqo1gDrXuULw2Qtw=; b=KTeUWEvrGH8xsZ03QGtnC121pVWPDADzP7cMOoV0wtr3wNP5RzaBaX9cnZziNjujN+ t81ye2FO4wU+6fzfrKphLHGgLs3L0UwZm/voTcLpEEOXmR1J3h0YWPJxjtUm6IpUR8Oa MMs1oWDzaIjDH+iP7to16M1tE4rzZ9n9ZLpa3oMYX+u8UR97TOZF+TGxOL+RjY6A6tt1 yvhIE0vvNklEK9XETtpcbfOEIM21TUIvwIRVaGdRIaQHkD2TYRnZlCJvL8klTiiF9YW4 OhoNZtbBAMWRI7P4XXYzQXw6MwQy0hr+vueSEkdlCfVTC7al0xR/T9/i73IVI+kBSqbo DJQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773756950; x=1774361750; 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=20jDT7vbb/pcwg3RWwDlyXHU14Ovqo1gDrXuULw2Qtw=; b=XCnSZOQgvMWBAwF/0US8FB1O9/jKM0Q+B0RSvd/kn+IbXXGv5lPJiQ0OLRKSYLHrz+ lzqDZN90+iiWHVOCVXAl/Kvm3QKYoiGSRhlVbPRNJ4t+qxUj5PvzrKqoEeJfKpALZvll DRLr+lHt7UVUY/I+p4TUiZpoXaMreAvYmiEjL+aDjYKcU769e83H06tNsvBjzsvP+k0u VpeF1wNWO3vViy4EsWUqw9i8PRC2VMhpGAn/qRooDs7u2/yz3jBdCj3zWGN54oNZEC50 hs338fExZ5L1rzUPVvR0r/fKCJmLc74THG0B5CZjqjeZVcLZfMO4kDfF9VeCBFrsz0+5 S7fA== X-Gm-Message-State: AOJu0YyX3UvR64+mg5x/GKnzLSUajNIgbyHJndTZMEUFhzuqmLJ//4mC 97JoKqNV93u3RCSdAfeD+D8XGfBaKSPPbEYqgiCcXrGdhk0KDcamfbPS15+oijZd+bfTG78LlpH 0X2hIyYubryMUO9YhbRcDlQ== X-Received: from wmpj20.prod.google.com ([2002:a05:600c:4894:b0:485:3c21:d5f0]) (user=mclapinski job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b45:b0:485:30d4:6b9e with SMTP id 5b1f17b1804b1-48556702853mr281166825e9.21.1773756950287; Tue, 17 Mar 2026 07:15:50 -0700 (PDT) Date: Tue, 17 Mar 2026 15:15:34 +0100 In-Reply-To: <20260317141534.815634-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: <20260317141534.815634-1-mclapinski@google.com> X-Mailer: git-send-email 2.53.0.851.ga537e3e6e9-goog Message-ID: <20260317141534.815634-4-mclapinski@google.com> Subject: [PATCH v7 3/3] 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 e511a50fab9c..b49ebcd0b946 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.851.ga537e3e6e9-goog