From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 03BD8266581; Sat, 6 Dec 2025 23:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765062206; cv=none; b=ZU6xKCLwn1HqsTAWGsDIIPiRm4RPVSTU0dzgO63zxu2LHPZBANjRuzG9VblOSrS4lG2XmTZX7e4PHVSegRko+yjFvtJp4Zg0acWqlDSpACynaYyOzbqUBlVB1L/z12xvuFZ/nCHI5Cka/WEDny3skwupvAMBFDOYTeVgZCU/dXQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765062206; c=relaxed/simple; bh=KGnOcfnpQ9BU9FZJbzrgiU8lnduu/8HRPawdKcV6t1k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GgFQHIHWccWdE/j1oSCSOKixd+46WOU6DhkfZinaqaBdpUWW+iJe5wHGZylfvUixCEsW0V4gHko2EZOMn5XUAqwhIkNV+9H1pJOVDL4GwNU2w/+UjC3NuyNiCOBlbnyEc8Wx9TPLPimgtn+0gACr1es3rNrSqJUj+OUoj1PmBpI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tUUDtxnD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tUUDtxnD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE274C4CEF5; Sat, 6 Dec 2025 23:03:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765062205; bh=KGnOcfnpQ9BU9FZJbzrgiU8lnduu/8HRPawdKcV6t1k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tUUDtxnD5j/gPnDazGeJDlVfGjKWIZmBD0OblMoGkBSR3WryqOqAP2BtduJHW0Ts1 zib5G2oPsbnoO0PpF3BE0aBcSjgf6rrxSEeHGJHAqhF6kJ1LszXt5G2ohGlc6+yUdy s1fCdKColhX6jzjtk3VgF8N3NHN5Ai/CNEdqHnMiqpgkchklfoS77EULfkVIzP83kL M4+grCe+p4WBo9sEMdr8CqWz1LBua/gXhaTVXsVMG/RhWBproCM+CptJ+pjKgNbYVp fqabR6XaYXZQVJh7v5K0/LZS5/J14mfdaibZoq4izdmEGRDNVjD6mVEdyWP87vNXgC jzCJjlTmsF/Gw== From: Pratyush Yadav To: Pasha Tatashin , Mike Rapoport , Pratyush Yadav , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Suren Baghdasaryan , Michal Hocko , Jonathan Corbet , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Muchun Song , Oscar Salvador , Alexander Graf , David Matlack , David Rientjes , Jason Gunthorpe , Samiullah Khawaja , Vipin Sharma , Zhu Yanjun Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, kexec@lists.infradead.org Subject: [RFC PATCH 04/10] liveupdate: flb: allow getting FLB data in early boot Date: Sun, 7 Dec 2025 00:02:14 +0100 Message-ID: <20251206230222.853493-5-pratyush@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251206230222.853493-1-pratyush@kernel.org> References: <20251206230222.853493-1-pratyush@kernel.org> Precedence: bulk X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit To support hugepage preservation using LUO, the hugetlb subsystem needs to get liveupdate data when it allocates the hugepages to find out how many pages are coming from live update. This data is preserved via LUO FLB. Since gigantic hugepage allocations happen before LUO (and much of the rest of the system) is initialized, the usual liveupdate_flb_get_incoming() can not work. Add a read-only variant that fetches the FLB data but does not trigger its retrieve or do any locking or reference counting. It is the caller's responsibility to make sure there are no side effects of using this data to the proper retrieve call that would happen later. Refactor the logic to find the right FLB in the serialized data in a helper that can be used from both luo_flb_retrieve_one() (called from luo_flb_get_incoming()), and from luo_flb_get_incoming_early(). Signed-off-by: Pratyush Yadav --- include/linux/liveupdate.h | 6 ++++ kernel/liveupdate/luo_flb.c | 69 +++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 78e8c529e4e7..39b429d2c62c 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -232,6 +232,7 @@ int liveupdate_unregister_flb(struct liveupdate_file_handler *fh, int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp); int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp); +int liveupdate_flb_incoming_early(struct liveupdate_flb *flb, u64 *datap); #else /* CONFIG_LIVEUPDATE */ @@ -283,5 +284,10 @@ static inline int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, return -EOPNOTSUPP; } +int liveupdate_flb_incoming_early(struct liveupdate_flb *flb, u64 *datap) +{ + return -EOPNOTSUPP; +} + #endif /* CONFIG_LIVEUPDATE */ #endif /* _LINUX_LIVEUPDATE_H */ diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index e80ac5b575ec..fb287734a88e 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -145,12 +145,25 @@ static void luo_flb_file_unpreserve_one(struct liveupdate_flb *flb) } } +static struct luo_flb_ser *luo_flb_find_ser(struct luo_flb_header *fh, + const char *name) +{ + if (!fh->active) + return ERR_PTR(-ENODATA); + + for (int i = 0; i < fh->header_ser->count; i++) { + if (!strcmp(fh->ser[i].name, name)) + return &fh->ser[i]; + } + + return ERR_PTR(-ENOENT); +} + static int luo_flb_retrieve_one(struct liveupdate_flb *flb) { struct luo_flb_private *private = luo_flb_get_private(flb); - struct luo_flb_header *fh = &luo_flb_global.incoming; struct liveupdate_flb_op_args args = {0}; - bool found = false; + struct luo_flb_ser *ser; int err; guard(mutex)(&private->incoming.lock); @@ -158,20 +171,12 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb) if (private->incoming.obj) return 0; - if (!fh->active) - return -ENODATA; + ser = luo_flb_find_ser(&luo_flb_global.incoming, flb->compatible); + if (IS_ERR(ser)) + return PTR_ERR(ser); - for (int i = 0; i < fh->header_ser->count; i++) { - if (!strcmp(fh->ser[i].name, flb->compatible)) { - private->incoming.data = fh->ser[i].data; - private->incoming.count = fh->ser[i].count; - found = true; - break; - } - } - - if (!found) - return -ENOENT; + private->incoming.data = ser->data; + private->incoming.count = ser->count; args.flb = flb; args.data = private->incoming.data; @@ -188,6 +193,40 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb) return 0; } +/** + * liveupdate_flb_incoming_early - Fetch FLB data in early boot. + * @flb: The FLB definition + * @datap: Pointer to serialized state handle of the FLB + * + * This function is intended to be called during early boot, before the + * liveupdate subsystem is fully initialized. It must only be called after + * liveupdate_early_init(). + * + * Directly returns the u64 handle to the serialized state of the FLB, and does + * not trigger its retrieve. A later fetch of the FLB will trigger the retrieve. + * Callers must make sure there are no side effects because of this. + * + * Return: 0 on success, -errno on failure. -ENODATA means no incoming FLB data, + * -ENOENT means specific FLB not found in incoming data, and -EOPNOTSUPP when + * live update is disabled or not early initialization not finished. + */ +int __init liveupdate_flb_incoming_early(struct liveupdate_flb *flb, u64 *datap) +{ + struct luo_flb_ser *ser; + + if (!luo_early_initialized()) { + pr_warn("LUO FLB retrieved before LUO early init!\n"); + return -EOPNOTSUPP; + } + + ser = luo_flb_find_ser(&luo_flb_global.incoming, flb->compatible); + if (IS_ERR(ser)) + return PTR_ERR(ser); + + *datap = ser->data; + return 0; +} + static void luo_flb_file_finish_one(struct liveupdate_flb *flb) { struct luo_flb_private *private = luo_flb_get_private(flb); -- 2.43.0