From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (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 097673161A2 for ; Sat, 30 May 2026 22:19:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179586; cv=none; b=DWHjJ/xRwMkHofb3RDvihYPdEL+sonJ3oEDdf3BuQPuJNetZ+rYbyWMOzHBBMrgr1xmkos0tzWpqF53/yh3OuBSlJtBTR3RGMcirrWVE/bmpxuLGazNytA+zr+2HiDeXQsWQcbF2aLdalIL3SEiURtsb2auVF8HK+2+VGLJ2zHM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179586; c=relaxed/simple; bh=dq6VJL19bx4fk8daGhAlZmCEZx9LJQRuBBgg8TWS9rQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u+mAqI8RPMnFy/w+nXPW2rnxo7kpk1S5rpDFpexrsW9kSbDlwe0sIbgg0yQmb/eLDdkF8kdyiTN95hAKpoBEPJ96fo/er2iMSoiW/3gwOiRodI8oaXTbHs/HVI2YkT7qYA8g4yEfWgO938ROO6GpFXoAUGpfmaHMzz9qPge7VOM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=cvuTZsH/; arc=none smtp.client-ip=209.85.222.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="cvuTZsH/" Received: by mail-qk1-f179.google.com with SMTP id af79cd13be357-91550dda53cso32269185a.1 for ; Sat, 30 May 2026 15:19:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179584; x=1780784384; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=087/smJrDH1Ri/FmSC9bbtTtLl+ESvDrae9U9V2wtSI=; b=cvuTZsH/od0mvFzcMzuphLBK2Gi0IRpU7tj7/MlSSWKVugWSdrJ0uRdC8Z9//oJpNP ipABiRbvbdAuwcP2e8s+ku+TwCTv75lXIgagypyJuGXjuyBP66f7wg4vopz04GeHpkdM ht2yzN3xqnqtSZcRJciz6AHH1924BEAnlBhFxTZQqgZAmfNoBALuWauv8SMMhbC4fgtx COvpCTeQWLulqHgVPixW4O79r1f4xedYKhim7RxkuJkAM6al31lIlvhjtxuQe78U00uH y9MxQyVjDqzYmYuWXatebpZO6uqUr9EKkvzqpqZf599/OpqDyZnN2Jqn2TqYnZqpeCDC guVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179584; x=1780784384; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=087/smJrDH1Ri/FmSC9bbtTtLl+ESvDrae9U9V2wtSI=; b=fHnukChtCbFwnzphKRraemkvbfl8BaFeOrivi/geqwGOgqf2oyldB+GK5/0TX39qHT S9gNHUCA9ssloFU2yZ41F3hnYVlnfDGfAGyZZlhFdybKsypS6g6XQCNYRuoORXr315gf XwHFLxHPPvingdj6m49CEeRBiSZmWycdaZeo3Ed4ykpkLVAOkMjFDk9xCusypZj7eDve x/Fdogb2sKUZFf9dNxQ+RTpcpApIiMklauFbjt1AHHNiy2g1DUfYapRPdwuh3XQf4Q2Y tX0EMebOiFk1LuGf6UGxZ0x7SgQyZKe95AS0s+1QhAPI4niFQx+JV9EYixa7bYqKIN3Z D6Nw== X-Forwarded-Encrypted: i=1; AFNElJ/VH7iE5kReuUKw9IpfbN/Y2zmGO3LiAr1zBM0NiukaiMr4PFSKjdmOAeZtl7ovbIqq9f/WyrjnditnVG4=@vger.kernel.org X-Gm-Message-State: AOJu0YxB5s/StOpsU71AM+dL9vUeg+Oa23rDZ8JKbGbvEfO5beNjTgOi +pFVd+0Zv+EM1XyQTQZKHmWGfU6iFuga4w3ElrGDvv1NOlZUyoFH+gQ+8FIN8dxs4Fg= X-Gm-Gg: Acq92OGYC6QVu8clG8Mnj/E2YE0rft4lxD0R6M2ZOARxZEMnJZuDsCbvsj6adO8LFWG CxT5XvNBCpxhqp6g47e+gk+NEKq87K1KOgLM0cYnUC9AuIcr5qr1FEs78W3QmZyo5KZkwnUOWsQ BFAAFwNjwzRqlGdhEIG8yuJMRC2BeseoR5qWNckp5ckCPfFa/VHqDI0HvdsQoxEZ9f6VQ/QvQ1p +rml5v7OQiT7piIMHEHWR4evzSK3sswEY2Z9PtvMaGWYJ3WzC13uVmjD6cLAMjdBIGyQP+ubCEp I+gjV5mk7+2wT9DR6KMNYzPUZblWGs7Na0OpDr0VbzkeoAcmjfW1ts1KMK99KYeQx/WVP6D0WSz Q9zg0MvRO3sHDsMZ+LqB6bwNRgmAfi/pqY+XX/4KjKtXHkU5U+9c1Bx6nFJE8z+j8OgyHGoBZMq MJ7OtuNt4Cgt+A2l6VxmULVE6R/yN5Vr/RP+4vaz/EDXqvduYO6fcOmV/Cf/ESSQ== X-Received: by 2002:a05:620a:4053:b0:911:449d:98c0 with SMTP id af79cd13be357-9153d9cb08emr793370385a.7.1780179584086; Sat, 30 May 2026 15:19:44 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:42 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 01/13] liveupdate: change file_set->count type to u64 for type safety Date: Sat, 30 May 2026 22:19:26 +0000 Message-ID: <20260530221938.115978-2-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This improves type safety and aligns the in-memory file_set->count with the serialized count type. It avoids potential truncation or sign conversion mismatch issues. Signed-off-by: Pasha Tatashin Acked-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav (Google) --- kernel/liveupdate/luo_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_inter= nal.h index dd53d4a7277e..ae58206f14ac 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -52,7 +52,7 @@ static inline int luo_ucmd_respond(struct luo_ucmd *ucmd, struct luo_file_set { struct list_head files_list; struct luo_file_ser *files; - long count; + u64 count; }; =20 /** --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (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 D1827366553 for ; Sat, 30 May 2026 22:19:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179593; cv=none; b=bBZU3NfXSeihpxpY2DE391rzan/3GYxQW8fiyHUq8YroN/aRcL2ANXiqVileMMGFEo8CRSNCV7G/lUEvnGAqyj+VRjnKqHDjsIqje9KwEJDirPzIfFhsVjrnozDhtdb5YXukHDMYedyEqqX+v5XnpIixv1lqvpH1ljtgxEtuvVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179593; c=relaxed/simple; bh=uuNTx4qc25JmiOtcSrZROc24eW3q0s0py3Ks6ODa+Po=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WsfLn9KutE5O78sbtPU6EJ6j3ASvyYa93zvnNWbmjZl1SXeD2pgT2Ii4aPj14ovbZmXVHXvC2Y96dIn+x5C2gWDlJgqBTnMWPKc+4bQwnZaryl2ds+O/a4A4M0UpKIHYxgZFDVSLyOV9H7QYk09SCiZ+uT81nwS0fi2qXI2aq2g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=YBZR1kCO; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="YBZR1kCO" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-91550fe1619so19650585a.3 for ; Sat, 30 May 2026 15:19:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179587; x=1780784387; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=HTj0tA/bHNpv873y+awGsfoidHwlRovW0AIu32f5CU8=; b=YBZR1kCO+cVsB30CoEvIEbqeAFusIfaEDphvXJfAZRGbfyQpB2dBXuiKt7BUzhRKi4 G9UR79BIDTBExj5vIaPEVZd6f0NdDn2Y8jkWrWIaJ0G+GZ7w/v/HMK/KDKLLQvCq76H0 aro2OS/5v4gnBVq7emDCrR4jsGCMgTaOexavhALohtf4G6qB+zpetFfehVtBeKxGNRFh qjAaMiC20Jb/Iu7I3xdgX5uguKu6flyJywld+x0lViXrz0Sxdw9/H9j8NAi/Xq/1X9M5 RBe/ROQaGtB+A0M3VC80F9s6VKNFjqTT3jnnCe6vC2c+hPGOjYIt+RE458v07jxVKZEx 8i7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179587; x=1780784387; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=HTj0tA/bHNpv873y+awGsfoidHwlRovW0AIu32f5CU8=; b=ZuEyG8RRg1OY81UihbHJPVIoBj2ANSPiTr/nUQYjB+sr60dJhk4YFfK5o89F0roxWx dLKjyuLKyqz7B7UKAGXUmI2tPTDFtxarIyu5FE5XBusl/qmKnE16KkO5PjEOHdXlHN4z 5+856szYZoONrlxCeQMkQgy1Rl7oeA+zmkfVLSInV7bj2oXTe457NGe7xun85suRB1RV AqCNKdd5V6dg/9KzDzX60elWUokr09c6gh3QUOpMUyc1+2sGm7+igDnMzRI1A/AiVcLe 0PDHbPdJSotIa01aZAzmwhglNesLIjOdQTUGF4KOT3Pe1MyHstBMXAayliDN0VLzd0kB BgGQ== X-Forwarded-Encrypted: i=1; AFNElJ/iLZcIBRaE0LkDJFuz1KJkwQK4CT/X2qjXEOSpHDBbw2jcLoKYGm4/M4XuNNRfmSHUWlPBbVSD+oQ2Ah4=@vger.kernel.org X-Gm-Message-State: AOJu0Ywmk5Uyr+igGNUc8f20MZRQXLiu+tt9UQhZYfCzpRlLWIgobEbY a2ejXfWhMCFq+jm0/KcLni0P2FAjZLVuI+sku4EeQQAp+i5etMIkQ1+1g9Jm0pP5Y9E= X-Gm-Gg: Acq92OHYu/6+bD4zaIFnGnJYXfc93BjEnHDD1+DmO9YG0lSXDH9VMVRNSqs3HUK0aXx 9xNGhZUR1eEvTM5MvMOVz+uMEO2+YLKHif+Yodxvi8qmd4cw2pSSTwOoe9cQOOmy8rPOzRCjafl 1Z6SHKdwO8ouhqkUHbh1JNVydp5eTmC5R3rKA8VHzPhwpgSiU18eXcPSdzm36ewyJhzyn4Ip4my nZmuskM/MlPxPwdFCy85gxmGK0KevzrtorNnOw5Qv3VBpOyMTrDtzb2p5Du+lp6dzw1AHefZgKL ZQOzhAS0L+hcyhzOfgAGAki7b5071fNvi+73wvran85+JhzD6xpGKHIwxIF6dR8OjnyiYGb43H3 tJ12oazUJmBRozWg7S6+AF5DjmO6kK1Gs1FLjNEjh1jTRFMdXugCf/Ql7YuFwadzRQmI12kvrDt MC3/21sMpjijY930RQCBepoieMRCboNmNWnbkg+hbYDDu6Mddx0o6pAZ2IVX+KEQ== X-Received: by 2002:a05:620a:2610:b0:8f8:cdd0:df82 with SMTP id af79cd13be357-9153dcb4b99mr859487985a.58.1780179586864; Sat, 30 May 2026 15:19:46 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:45 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 02/13] liveupdate: avoid mixing cleanup guards with goto in luo_session_retrieve_fd Date: Sat, 30 May 2026 22:19:27 +0000 Message-ID: <20260530221938.115978-3-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Refactoring luo_session_retrieve_fd() to avoid mixing automated cleanup-style guards with goto-based resource release, which is not recommended under the Linux kernel coding style. Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- kernel/liveupdate/luo_session.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index 146414933977..8d9201c25412 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -291,25 +291,24 @@ static int luo_session_retrieve_fd(struct luo_session= *session, if (argp->fd < 0) return argp->fd; =20 - guard(mutex)(&session->mutex); - err =3D luo_retrieve_file(&session->file_set, argp->token, &file); - if (err < 0) - goto err_put_fd; + scoped_guard(mutex, &session->mutex) { + err =3D luo_retrieve_file(&session->file_set, argp->token, &file); + if (err < 0) { + put_unused_fd(argp->fd); + return err; + } + } =20 err =3D luo_ucmd_respond(ucmd, sizeof(*argp)); - if (err) - goto err_put_file; + if (err) { + fput(file); + put_unused_fd(argp->fd); + return err; + } =20 fd_install(argp->fd, file); =20 return 0; - -err_put_file: - fput(file); -err_put_fd: - put_unused_fd(argp->fd); - - return err; } =20 static int luo_session_finish(struct luo_session *session, --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f181.google.com (mail-qk1-f181.google.com [209.85.222.181]) (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 A31AF279DC9 for ; Sat, 30 May 2026 22:19:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179592; cv=none; b=dig7XXJcBEXdFEop6x6jLoAws5i2eK51ARGtDTmG1eKlgBbFMKP2Gs+2b9GqahqJIuFwQO+4zH2R4Uf9GQZAG/5GJ3yA5up2+xHfsPLwItiNf8Z+0UNHX6h1ySSGHn+rhRr9cv0NA3IL7WS0zll2bI22rWQI8dLY63zGjtr67G8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179592; c=relaxed/simple; bh=4aRPU+84gtVjTHViBw9XmqjUqzYPIsjjVQcVqZqdugc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DAPNS+yBZtDmSFllJ2i/sQ4AU6OnsAhFt6cFN8szPTwdJrNMzIXzJL7FTOISzwHCXKPQv6bdUxIRPTeDSK+fY/GbzJx28qEqiCk7PpZd1Swsa63LXqoFrbjcPWEx8kJhXh9/hpihRZeKv+bJ/d6GCyOhGwSqAtRV+qSVVc/Nzn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=CCh+Tf7q; arc=none smtp.client-ip=209.85.222.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="CCh+Tf7q" Received: by mail-qk1-f181.google.com with SMTP id af79cd13be357-914db409f1bso528424085a.3 for ; Sat, 30 May 2026 15:19:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179590; x=1780784390; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=0Z6wfVVtfAWGtq89P4r4OtH0ae/bFbq+ZIhi4xl+2Ck=; b=CCh+Tf7q8pJiO6vSUN6HFYGDHRz8c+wHx17TzWGpiFrdLPoJ34aen4O2OqobwBmnfi AIBcUB0AqBq5r/XP3Jrz+4G8lc9sLD98RY5pBRdpzmK4c/DGMg3yCj8QMSsZ/WYb5Rop Xipffp26fHkxczKohcSSBwr9srqFNKuffJrDbnvQuU2RW3M0ZnzHcAmUs7vELAAgE061 bndLsXKnla5YSARuS8UQM5+f5Qe1rN97XIYR0cewcPqE1OHdkR3jewlQjDpu1irHSj28 B8Rg9Kv64QlegHXiLRcIQzvIt9mih0pLAqi5mIqUyvzC7IABeJPieZ0TF3Hyq2WXh5ui 0mOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179590; x=1780784390; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=0Z6wfVVtfAWGtq89P4r4OtH0ae/bFbq+ZIhi4xl+2Ck=; b=AKc/Cs8aGVzaQH0utPJC6LWelvvtwQ/3SRm7ravrWXob4y7KK6skjFSMj5FKD9bjPP b6f7iYJmJUDsclSQfUHskVhuJ5XBEDqQcC1WDajw9PjT1FRJqulY4QNftt4GyMxLbMu1 rGknnHNJWiwmWPOseBim1rOpqlmMERjC9u+bJD1AX8Dwqbz2baf+vkjXp0PSBSAXcBay o8akm274jrmwqHJsljFtPN3AbnE0luLpkTxOzm6ah2uEiQnoASX8wQzdsSnd7HOzIRp/ bxc4wMXw/OtTDpac+1NcJ39sL3cdfhJ8bMq7M6sBdN1pPA5uTwQs4bku1zKL0D+p7YuV L4VQ== X-Forwarded-Encrypted: i=1; AFNElJ/rUwIJ0s38s/Zrj+6znsmd+14dIS5BsgWDSfhdWP9Apr9rCBKcix7msR/1/etG2TDIEZzh9hDzQbvA3c8=@vger.kernel.org X-Gm-Message-State: AOJu0YzkNwUEBsJVeN92IzC0pk95y9QfzkiNO01B0v+FPu0rZTMwySsI aknyIcNYy5y9PDkImY0bFA3ipLiRK4+mAXIcJPMV/sNVMHYMy4PjDzXwqcpZtyHlo6Q= X-Gm-Gg: Acq92OFcMwA3nXwSTUlhopb3oq1y6Bc6zbjQlbZscYrzp/YhTaxLTt4rYl1K3qYvCeC /ktOq3/8kQ3Kgv5zZsl4Eef4wU5IQWhZJHstKii50m3jb2JUsbgfT93Hfd6oIHY0x+Lf0NAwDQS 2/LiGWeketVLJelqIIp5c1CqwUEV6iZXwGWeA8HpzYnzBrGcr+TDPU/FVuZ5/XKDk9rJ8EFjKy3 fYfg7A7C+jb+PDHq9F1wpoZazi0vwa5RS+jFE8wyA1tfpQ/hI4OGTbdteoQCt3L3ggj7JIez5qX 2b4/G9evxD15X+zDbaP2wdrqC5/w7GhiqAGb7QG0UiiJ4KxOA3E0szHZK6wzvjxVQGQHzOcLu7g w1JAFtoqjcsWnttQk6CbmM3oPpOrsMOF00/zEEzln42zpvGtIGN5scB3cWqcKekO6con5QjWMqN VTsA4UWaYMoRHp5/EZA0F6pGeSgGU7vzW8kbduU2fku6nhCv70T50N9LtqSaq60g== X-Received: by 2002:a05:620a:198f:b0:913:e5bb:3dc9 with SMTP id af79cd13be357-9153db718bdmr793177285a.57.1780179589568; Sat, 30 May 2026 15:19:49 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:48 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 03/13] liveupdate: centralize state management into struct luo_ser Date: Sat, 30 May 2026 22:19:28 +0000 Message-ID: <20260530221938.115978-4-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Transition the LUO to ABI v2, which centralizes state management into a single struct luo_ser header. Previously, LUO state was spread across multiple FDT properties and subnodes. ABI v2 simplifies this by placing all core state, including the liveupdate number and physical addresses for sessions and FLB headers into a centralized struct luo_ser. Note that this change introduces a semantic difference: the sessions and FLB serialization formats are no longer completely independent of the core LUO. Their metadata (such as physical addresses for sessions and FLB headers) is now coupled to and managed via the centralized struct luo_ser. Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- include/linux/kho/abi/luo.h | 91 +++++++++++--------------------- kernel/liveupdate/luo_core.c | 64 +++++++++++++++------- kernel/liveupdate/luo_flb.c | 65 +++-------------------- kernel/liveupdate/luo_internal.h | 8 +-- kernel/liveupdate/luo_session.c | 64 ++++------------------ 5 files changed, 98 insertions(+), 194 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 46750a0ddf88..1b2f865a771a 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -30,52 +30,25 @@ * .. code-block:: none * * / { - * compatible =3D "luo-v1"; - * liveupdate-number =3D <...>; - * - * luo-session { - * compatible =3D "luo-session-v1"; - * luo-session-header =3D ; - * }; - * - * luo-flb { - * compatible =3D "luo-flb-v1"; - * luo-flb-header =3D ; - * }; + * compatible =3D "luo-v2"; + * luo-abi-header =3D ; * }; * * Main LUO Node (/): * - * - compatible: "luo-v1" + * - compatible: "luo-v2" * Identifies the overall LUO ABI version. - * - liveupdate-number: u64 - * A counter tracking the number of successful live updates performed. - * - * Session Node (luo-session): - * This node describes all preserved user-space sessions. - * - * - compatible: "luo-session-v1" - * Identifies the session ABI version. - * - luo-session-header: u64 - * The physical address of a `struct luo_session_header_ser`. This str= ucture - * is the header for a contiguous block of memory containing an array = of - * `struct luo_session_ser`, one for each preserved session. - * - * File-Lifecycle-Bound Node (luo-flb): - * This node describes all preserved global objects whose lifecycle is b= ound - * to that of the preserved files (e.g., shared IOMMU state). - * - * - compatible: "luo-flb-v1" - * Identifies the FLB ABI version. - * - luo-flb-header: u64 - * The physical address of a `struct luo_flb_header_ser`. This structu= re is - * the header for a contiguous block of memory containing an array of - * `struct luo_flb_ser`, one for each preserved global object. + * - luo-abi-header: u64 + * The physical address of `struct luo_ser`. * * Serialization Structures: * The FDT properties point to memory regions containing arrays of simpl= e, * `__packed` structures. These structures contain the actual preserved = state. * + * - struct luo_ser: + * The central ABI structure that contains the overall state of the LU= O. + * It includes the liveupdate-number and pointers to sessions and FLBs. + * * - struct luo_session_header_ser: * Header for the session array. Contains the total page count of the * preserved memory block and the number of `struct luo_session_ser` @@ -109,13 +82,26 @@ =20 /* * The LUO FDT hooks all LUO state for sessions, fds, etc. - * In the root it also carries "liveupdate-number" 64-bit property that - * corresponds to the number of live-updates performed on this machine. */ #define LUO_FDT_SIZE PAGE_SIZE #define LUO_FDT_KHO_ENTRY_NAME "LUO" -#define LUO_FDT_COMPATIBLE "luo-v1" -#define LUO_FDT_LIVEUPDATE_NUM "liveupdate-number" +#define LUO_FDT_COMPATIBLE "luo-v2" +#define LUO_FDT_ABI_HEADER "luo-abi-header" + +/** + * struct luo_ser - Centralized LUO ABI header. + * @liveupdate_num: A counter tracking the number of successful live updat= es. + * @sessions_pa: Physical address of the first session block header. + * @flbs_pa: Physical address of the FLB header. + * + * This structure is the root of all preserved LUO state. It is pointed to= by + * the "luo-abi-header" property in the LUO FDT. + */ +struct luo_ser { + u64 liveupdate_num; + u64 sessions_pa; + u64 flbs_pa; +} __packed; =20 #define LIVEUPDATE_HNDL_COMPAT_LENGTH 48 =20 @@ -147,15 +133,6 @@ struct luo_file_set_ser { u64 count; } __packed; =20 -/* - * LUO FDT session node - * LUO_FDT_SESSION_HEADER: is a u64 physical address of struct - * luo_session_header_ser - */ -#define LUO_FDT_SESSION_NODE_NAME "luo-session" -#define LUO_FDT_SESSION_COMPATIBLE "luo-session-v2" -#define LUO_FDT_SESSION_HEADER "luo-session-header" - /** * struct luo_session_header_ser - Header for the serialized session data = block. * @count: The number of `struct luo_session_ser` entries that immediately @@ -165,7 +142,7 @@ struct luo_file_set_ser { * physical memory preserved across the kexec. It provides the necessary * metadata to interpret the array of session entries that follow. * - * If this structure is modified, `LUO_FDT_SESSION_COMPATIBLE` must be upd= ated. + * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. */ struct luo_session_header_ser { u64 count; @@ -182,7 +159,7 @@ struct luo_session_header_ser { * session) is created and passed to the new kernel, allowing it to recons= truct * the session context. * - * If this structure is modified, `LUO_FDT_SESSION_COMPATIBLE` must be upd= ated. + * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. */ struct luo_session_ser { char name[LIVEUPDATE_SESSION_NAME_LENGTH]; @@ -192,10 +169,6 @@ struct luo_session_ser { /* The max size is set so it can be reliably used during in serialization = */ #define LIVEUPDATE_FLB_COMPAT_LENGTH 48 =20 -#define LUO_FDT_FLB_NODE_NAME "luo-flb" -#define LUO_FDT_FLB_COMPATIBLE "luo-flb-v1" -#define LUO_FDT_FLB_HEADER "luo-flb-header" - /** * struct luo_flb_header_ser - Header for the serialized FLB data block. * @pgcnt: The total number of pages occupied by the entire preserved memo= ry @@ -205,11 +178,9 @@ struct luo_session_ser { * in the memory block. * * This structure is located at the physical address specified by the - * `LUO_FDT_FLB_HEADER` FDT property. It provides the new kernel with the - * necessary information to find and iterate over the array of preserved - * File-Lifecycle-Bound objects and to manage the underlying memory. + * flbs_pa in luo_ser. * - * If this structure is modified, LUO_FDT_FLB_COMPATIBLE must be updated. + * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. */ struct luo_flb_header_ser { u64 pgcnt; @@ -231,7 +202,7 @@ struct luo_flb_header_ser { * passed to the new kernel. Each entry allows the LUO core to restore one * global, shared object. * - * If this structure is modified, LUO_FDT_FLB_COMPATIBLE must be updated. + * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. */ struct luo_flb_ser { char name[LIVEUPDATE_FLB_COMPAT_LENGTH]; diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index 803f51c84275..fbc18c5f4230 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -57,7 +57,6 @@ #include #include #include -#include =20 #include "kexec_handover_internal.h" #include "luo_internal.h" @@ -82,9 +81,11 @@ early_param("liveupdate", early_liveupdate_param); =20 static int __init luo_early_startup(void) { + struct luo_ser *luo_ser; + int err, header_size; phys_addr_t fdt_phys; - int err, ln_size; const void *ptr; + u64 luo_ser_pa; =20 if (!kho_is_enabled()) { if (liveupdate_enabled()) @@ -115,26 +116,32 @@ static int __init luo_early_startup(void) return -EINVAL; } =20 - ln_size =3D 0; - ptr =3D fdt_getprop(luo_global.fdt_in, 0, LUO_FDT_LIVEUPDATE_NUM, - &ln_size); - if (!ptr || ln_size !=3D sizeof(luo_global.liveupdate_num)) { - pr_err("Unable to get live update number '%s' [%d]\n", - LUO_FDT_LIVEUPDATE_NUM, ln_size); + header_size =3D 0; + ptr =3D fdt_getprop(luo_global.fdt_in, 0, LUO_FDT_ABI_HEADER, &header_siz= e); + if (!ptr || header_size !=3D sizeof(u64)) { + pr_err("Unable to get ABI header '%s' [%d]\n", + LUO_FDT_ABI_HEADER, header_size); =20 return -EINVAL; } =20 - luo_global.liveupdate_num =3D get_unaligned((u64 *)ptr); + luo_ser_pa =3D get_unaligned((u64 *)ptr); + luo_ser =3D phys_to_virt(luo_ser_pa); + + luo_global.liveupdate_num =3D luo_ser->liveupdate_num; pr_info("Retrieved live update data, liveupdate number: %lld\n", luo_global.liveupdate_num); =20 - err =3D luo_session_setup_incoming(luo_global.fdt_in); + err =3D luo_session_setup_incoming(luo_ser->sessions_pa); if (err) - return err; + goto out_free_ser; + + luo_flb_setup_incoming(luo_ser->flbs_pa); =20 - err =3D luo_flb_setup_incoming(luo_global.fdt_in); + err =3D 0; =20 +out_free_ser: + kho_restore_free(luo_ser); return err; } =20 @@ -156,7 +163,8 @@ early_initcall(liveupdate_early_init); /* Called during boot to create outgoing LUO fdt tree */ static int __init luo_fdt_setup(void) { - const u64 ln =3D luo_global.liveupdate_num + 1; + struct luo_ser *luo_ser; + u64 luo_ser_pa; void *fdt_out; int err; =20 @@ -166,27 +174,45 @@ static int __init luo_fdt_setup(void) return PTR_ERR(fdt_out); } =20 + luo_ser =3D kho_alloc_preserve(sizeof(*luo_ser)); + if (IS_ERR(luo_ser)) { + err =3D PTR_ERR(luo_ser); + goto exit_free_fdt; + } + luo_ser_pa =3D virt_to_phys(luo_ser); + err =3D fdt_create(fdt_out, LUO_FDT_SIZE); err |=3D fdt_finish_reservemap(fdt_out); err |=3D fdt_begin_node(fdt_out, ""); err |=3D fdt_property_string(fdt_out, "compatible", LUO_FDT_COMPATIBLE); - err |=3D fdt_property(fdt_out, LUO_FDT_LIVEUPDATE_NUM, &ln, sizeof(ln)); - err |=3D luo_session_setup_outgoing(fdt_out); - err |=3D luo_flb_setup_outgoing(fdt_out); + err |=3D fdt_property(fdt_out, LUO_FDT_ABI_HEADER, &luo_ser_pa, + sizeof(luo_ser_pa)); err |=3D fdt_end_node(fdt_out); err |=3D fdt_finish(fdt_out); if (err) - goto exit_free; + goto exit_free_luo_ser; + + err =3D luo_session_setup_outgoing(&luo_ser->sessions_pa); + if (err) + goto exit_free_luo_ser; + + err =3D luo_flb_setup_outgoing(&luo_ser->flbs_pa); + if (err) + goto exit_free_luo_ser; + + luo_ser->liveupdate_num =3D luo_global.liveupdate_num + 1; =20 err =3D kho_add_subtree(LUO_FDT_KHO_ENTRY_NAME, fdt_out, fdt_totalsize(fdt_out)); if (err) - goto exit_free; + goto exit_free_luo_ser; luo_global.fdt_out =3D fdt_out; =20 return 0; =20 -exit_free: +exit_free_luo_ser: + kho_unpreserve_free(luo_ser); +exit_free_fdt: kho_unpreserve_free(fdt_out); pr_err("failed to prepare LUO FDT: %d\n", err); =20 diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index 8f5c5dd01cd0..c8dd30b41238 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -44,13 +44,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include "luo_internal.h" =20 #define LUO_FLB_PGCNT 1ul @@ -551,27 +549,15 @@ int liveupdate_flb_get_outgoing(struct liveupdate_flb= *flb, void **objp) return 0; } =20 -int __init luo_flb_setup_outgoing(void *fdt_out) +int __init luo_flb_setup_outgoing(u64 *flbs_pa) { struct luo_flb_header_ser *header_ser; - u64 header_ser_pa; - int err; =20 header_ser =3D kho_alloc_preserve(LUO_FLB_PGCNT << PAGE_SHIFT); if (IS_ERR(header_ser)) return PTR_ERR(header_ser); =20 - header_ser_pa =3D virt_to_phys(header_ser); - - err =3D fdt_begin_node(fdt_out, LUO_FDT_FLB_NODE_NAME); - err |=3D fdt_property_string(fdt_out, "compatible", - LUO_FDT_FLB_COMPATIBLE); - err |=3D fdt_property(fdt_out, LUO_FDT_FLB_HEADER, &header_ser_pa, - sizeof(header_ser_pa)); - err |=3D fdt_end_node(fdt_out); - - if (err) - goto err_unpreserve; + *flbs_pa =3D virt_to_phys(header_ser); =20 header_ser->pgcnt =3D LUO_FLB_PGCNT; luo_flb_global.outgoing.header_ser =3D header_ser; @@ -579,53 +565,18 @@ int __init luo_flb_setup_outgoing(void *fdt_out) luo_flb_global.outgoing.active =3D true; =20 return 0; - -err_unpreserve: - kho_unpreserve_free(header_ser); - - return err; } =20 -int __init luo_flb_setup_incoming(void *fdt_in) +void __init luo_flb_setup_incoming(u64 flbs_pa) { struct luo_flb_header_ser *header_ser; - int err, header_size, offset; - const void *ptr; - u64 header_ser_pa; =20 - offset =3D fdt_subnode_offset(fdt_in, 0, LUO_FDT_FLB_NODE_NAME); - if (offset < 0) { - pr_err("Unable to get FLB node [%s]\n", LUO_FDT_FLB_NODE_NAME); - - return -ENOENT; + if (flbs_pa) { + header_ser =3D phys_to_virt(flbs_pa); + luo_flb_global.incoming.header_ser =3D header_ser; + luo_flb_global.incoming.ser =3D (void *)(header_ser + 1); + luo_flb_global.incoming.active =3D true; } - - err =3D fdt_node_check_compatible(fdt_in, offset, - LUO_FDT_FLB_COMPATIBLE); - if (err) { - pr_err("FLB node is incompatible with '%s' [%d]\n", - LUO_FDT_FLB_COMPATIBLE, err); - - return -EINVAL; - } - - header_size =3D 0; - ptr =3D fdt_getprop(fdt_in, offset, LUO_FDT_FLB_HEADER, &header_size); - if (!ptr || header_size !=3D sizeof(u64)) { - pr_err("Unable to get FLB header property '%s' [%d]\n", - LUO_FDT_FLB_HEADER, header_size); - - return -EINVAL; - } - - header_ser_pa =3D get_unaligned((u64 *)ptr); - header_ser =3D phys_to_virt(header_ser_pa); - - luo_flb_global.incoming.header_ser =3D header_ser; - luo_flb_global.incoming.ser =3D (void *)(header_ser + 1); - luo_flb_global.incoming.active =3D true; - - return 0; } =20 /** diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_inter= nal.h index ae58206f14ac..fe22086bfbeb 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -79,8 +79,8 @@ extern struct rw_semaphore luo_register_rwlock; =20 int luo_session_create(const char *name, struct file **filep); int luo_session_retrieve(const char *name, struct file **filep); -int __init luo_session_setup_outgoing(void *fdt); -int __init luo_session_setup_incoming(void *fdt); +int __init luo_session_setup_outgoing(u64 *sessions_pa); +int __init luo_session_setup_incoming(u64 sessions_pa); int luo_session_serialize(void); int luo_session_deserialize(void); =20 @@ -102,8 +102,8 @@ int luo_flb_file_preserve(struct liveupdate_file_handle= r *fh); void luo_flb_file_unpreserve(struct liveupdate_file_handler *fh); void luo_flb_file_finish(struct liveupdate_file_handler *fh); void luo_flb_unregister_all(struct liveupdate_file_handler *fh); -int __init luo_flb_setup_outgoing(void *fdt); -int __init luo_flb_setup_incoming(void *fdt); +int __init luo_flb_setup_outgoing(u64 *flbs_pa); +void __init luo_flb_setup_incoming(u64 flbs_pa); void luo_flb_serialize(void); =20 #ifdef CONFIG_LIVEUPDATE_TEST diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index 8d9201c25412..3b760fefa7b9 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -25,9 +25,8 @@ * * - Serialization: Session metadata is preserved using the KHO framework.= When * a live update is triggered via kexec, an array of `struct luo_session= _ser` - * is populated and placed in a preserved memory region. An FDT node is = also - * created, containing the count of sessions and the physical address of= this - * array. + * is populated and placed in a preserved memory region. The physical ad= dress + * of this array is stored in the centralized `struct luo_ser` structure. * * Session Lifecycle: * @@ -91,13 +90,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include "luo_internal.h" =20 @@ -497,75 +494,34 @@ int luo_session_retrieve(const char *name, struct fil= e **filep) return err; } =20 -int __init luo_session_setup_outgoing(void *fdt_out) +int __init luo_session_setup_outgoing(u64 *sessions_pa) { struct luo_session_header_ser *header_ser; - u64 header_ser_pa; - int err; =20 header_ser =3D kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT); if (IS_ERR(header_ser)) return PTR_ERR(header_ser); - header_ser_pa =3D virt_to_phys(header_ser); - - err =3D fdt_begin_node(fdt_out, LUO_FDT_SESSION_NODE_NAME); - err |=3D fdt_property_string(fdt_out, "compatible", - LUO_FDT_SESSION_COMPATIBLE); - err |=3D fdt_property(fdt_out, LUO_FDT_SESSION_HEADER, &header_ser_pa, - sizeof(header_ser_pa)); - err |=3D fdt_end_node(fdt_out); =20 - if (err) - goto err_unpreserve; + *sessions_pa =3D virt_to_phys(header_ser); =20 luo_session_global.outgoing.header_ser =3D header_ser; luo_session_global.outgoing.ser =3D (void *)(header_ser + 1); luo_session_global.outgoing.active =3D true; =20 return 0; - -err_unpreserve: - kho_unpreserve_free(header_ser); - return err; } =20 -int __init luo_session_setup_incoming(void *fdt_in) +int __init luo_session_setup_incoming(u64 sessions_pa) { struct luo_session_header_ser *header_ser; - int err, header_size, offset; - u64 header_ser_pa; - const void *ptr; - - offset =3D fdt_subnode_offset(fdt_in, 0, LUO_FDT_SESSION_NODE_NAME); - if (offset < 0) { - pr_err("Unable to get session node: [%s]\n", - LUO_FDT_SESSION_NODE_NAME); - return -EINVAL; - } =20 - err =3D fdt_node_check_compatible(fdt_in, offset, - LUO_FDT_SESSION_COMPATIBLE); - if (err) { - pr_err("Session node incompatible [%s]\n", - LUO_FDT_SESSION_COMPATIBLE); - return -EINVAL; + if (sessions_pa) { + header_ser =3D phys_to_virt(sessions_pa); + luo_session_global.incoming.header_ser =3D header_ser; + luo_session_global.incoming.ser =3D (void *)(header_ser + 1); + luo_session_global.incoming.active =3D true; } =20 - header_size =3D 0; - ptr =3D fdt_getprop(fdt_in, offset, LUO_FDT_SESSION_HEADER, &header_size); - if (!ptr || header_size !=3D sizeof(u64)) { - pr_err("Unable to get session header '%s' [%d]\n", - LUO_FDT_SESSION_HEADER, header_size); - return -EINVAL; - } - - header_ser_pa =3D get_unaligned((u64 *)ptr); - header_ser =3D phys_to_virt(header_ser_pa); - - luo_session_global.incoming.header_ser =3D header_ser; - luo_session_global.incoming.ser =3D (void *)(header_ser + 1); - luo_session_global.incoming.active =3D true; - return 0; } =20 --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) (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 C07C9377EBF for ; Sat, 30 May 2026 22:19:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179595; cv=none; b=cyCLcdIGrvSWSxuC4zplkmXawBpU7VGWwzbYXc2N9I3kYBLQWUum74ub4V7HBDMJnPGAhC0vryg+9Eape54tsAepUItdjH7ycEZHPsdKsBhIZYXpxToYEIEmzwDTThoXRZHzWh1yObvZgJRB2r+J6cQAP3EUDS82IHkNUw/ttMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179595; c=relaxed/simple; bh=Y2NfJsaLSRZHS3k0MvSySsg4UVJs9ht8kAGUUX3IXtw=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NZDc9vXi2hjU7rWTVCKKd98w21V1fnAdVS9icyjz6N44NF3CATTAaMtJ/e9ON0vBI2IplWGr4vTL9F4Td5diqcjzLjEBTowPXIcEK8QH6ZSkawTM+BIpyJ9WtckQ2kfi5G9mzlwvSaHGX3iwID7P6PmcMjZQcxoGw8JvzUI1rQ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=a+u0gSqz; arc=none smtp.client-ip=209.85.222.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="a+u0gSqz" Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-9155104b721so29925785a.3 for ; Sat, 30 May 2026 15:19:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179592; x=1780784392; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=XZQTZtc/bGyoFmxW6tJMa2O74TD8r2del+d8HujN8mY=; b=a+u0gSqzX38LRLUeowhCLEEbPxASYZNWgEOStvJH9ihfh5/ySp1RToTp1qovri6Yl8 3gud8sqh8VQFAU4BJA0rSIvmUhzpfO7TGH1JWv4TBYa/g575l3bxxAIp4tr2dR/8AOt/ jjUqEHesibHbHnnHbp5R6T9dabrqCqtKBFGtYh9NxKplop0dFHTnCly1wkmOo33bWLww isiSZDwPjdt4GgYPiZkaqy7HB0ptBPdQ4nO2twoNwpCfv1vOgS5SD1gYrKQFw7H/dCYu TMuTztNT+/0MXvXrAy9NWOqS2gJTb7atzxMEdcPU8YpzqEVj5wgoes+j1F/uBeDobZQf 7UMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179592; x=1780784392; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=XZQTZtc/bGyoFmxW6tJMa2O74TD8r2del+d8HujN8mY=; b=K1VTkSAQhJZzeMAjJjpQZLqoSywd0oZuF4SEdn/qjf4LfeC8kzh6FokpAXwGKOy5Ul O0HBUnjPZDjUauskYqqbozyn6WPvs8U2yYPlpFp8RHLs8e3eJwjiq+tIrRrBf5liHDEW ES9zO5LfWc76dXUoLPOvI2aBixAzhOVqywPHHJDe1KS3ilhM774aZ0UMKLPZH5+Xre71 lD+oHtXv4ZvJ8Yb9xO+8fe3SLpKKMx1WFh+NIo4aQCSY/XJW8D15oV/CQo95o6bgm16b 8qVu+FFRLdm/NMPKZuTCBv7dU9LSUrwXnzt/QGcVmO9AF/wK7UYCi1NGVNZhIAbMYYL3 pdYw== X-Forwarded-Encrypted: i=1; AFNElJ/w1YZfpY+2uya48FDO0Qz7NbXaK7NL8Zkal2DMACYkQ041K0psJxBnWCCJ3fB4oBK/qXwmwdurxHnhnqY=@vger.kernel.org X-Gm-Message-State: AOJu0Yyt+FlGZ42+2YkVasTWVpyEH0wpO79O9RCoE9aUI322PCBWLcpj NYq+ktta+IJZBuaCl2EVTWHZzcxUSaifGQW6U5uqpDvO01ffPWhcgygk7ahkXww7sys= X-Gm-Gg: Acq92OGmn1EcammamjYxJ7ol2Be9AlgJDShZYVYFGvqEXIUgh+OwIT6VAO0ltIKT/2Z f2el6Io9eRXk1CvEBZkWefyo+K6N0ep5WJqzzvdUv0owasLukV2vphCTjadQe4loyPWrY0CfCow 8iZb2fU+kqCh5NdRjmSCkZJg+BjEwE9m75bRq7HDYtM9Den1+qRExP+LFhpeOLYpk4dNvsdEJNm DHXCFxbHbpPpSG3Otb4XwbEaELMHD9kiz5bqQypVp7R+aJ/lWff+420TcuQaRnWPZ6yvVcAAcPN Nb2nLyWIW+u0WJ0j6P8hVgoDlzFh601eqfGKcnp6u0LEHTEIk9KHLe+9Fm6bFXlTQne/oQGk7tM y/7NOi0Qod7/ibp4Q7Hb7hHPTlNrfZExWTIQ6Rh8u+SoeKpxekYk5LJgZ9UDvZC5ntRf9E2ucwC 3gCBxvdDWJLDps311Z0tZEu1t7eYBgEgNATyoEoJ3AaDYpFxOkt8mjXCpxlh7EdQ== X-Received: by 2002:a05:620a:4549:b0:914:b9a2:f280 with SMTP id af79cd13be357-9153da34967mr740573085a.36.1780179591610; Sat, 30 May 2026 15:19:51 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:51 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 04/13] liveupdate: register luo_ser as KHO subtree Date: Sat, 30 May 2026 22:19:29 +0000 Message-ID: <20260530221938.115978-5-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Entirely remove the LUO FDT wrapper since the FDT only carries the compatible string and the pointer to the centralized struct luo_ser. Instead, register the struct luo_ser via the KHO raw subtree API, placing the compatibility string inside the structure itself. Signed-off-by: Pasha Tatashin --- include/linux/kho/abi/luo.h | 57 +++++++++--------------- kernel/liveupdate/luo_core.c | 85 +++++++++++------------------------- 2 files changed, 46 insertions(+), 96 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 1b2f865a771a..9a4fe491812b 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -10,11 +10,11 @@ * * Live Update Orchestrator uses the stable Application Binary Interface * defined below to pass state from a pre-update kernel to a post-update - * kernel. The ABI is built upon the Kexec HandOver framework and uses a - * Flattened Device Tree to describe the preserved data. + * kernel. The ABI is built upon the Kexec HandOver framework and registers + * the central `struct luo_ser` via the KHO raw subtree API. * - * This interface is a contract. Any modification to the FDT structure, no= de - * properties, compatible strings, or the layout of the `__packed` seriali= zation + * This interface is a contract. Any modification to the structure fields, + * compatible strings, or the layout of the `__packed` serialization * structures defined here constitutes a breaking change. Such changes req= uire * incrementing the version number in the relevant `_COMPATIBLE` string to * prevent a new kernel from misinterpreting data from an old kernel. @@ -23,31 +23,15 @@ * however, backward/forward compatibility is only guaranteed for kernels * supporting the same ABI version. * - * FDT Structure Overview: + * KHO Structure Overview: * The entire LUO state is encapsulated within a single KHO entry named = "LUO". - * This entry contains an FDT with the following layout: - * - * .. code-block:: none - * - * / { - * compatible =3D "luo-v2"; - * luo-abi-header =3D ; - * }; - * - * Main LUO Node (/): - * - * - compatible: "luo-v2" - * Identifies the overall LUO ABI version. - * - luo-abi-header: u64 - * The physical address of `struct luo_ser`. + * This entry contains the `struct luo_ser` structure. * * Serialization Structures: - * The FDT properties point to memory regions containing arrays of simpl= e, - * `__packed` structures. These structures contain the actual preserved = state. - * * - struct luo_ser: * The central ABI structure that contains the overall state of the LU= O. - * It includes the liveupdate-number and pointers to sessions and FLBs. + * It includes the compatibility string, the liveupdate-number, and po= inters + * to sessions and FLBs. * * - struct luo_session_header_ser: * Header for the session array. Contains the total page count of the @@ -78,26 +62,27 @@ #ifndef _LINUX_KHO_ABI_LUO_H #define _LINUX_KHO_ABI_LUO_H =20 +#include #include =20 /* - * The LUO FDT hooks all LUO state for sessions, fds, etc. + * The LUO state is registered under this KHO entry name. */ -#define LUO_FDT_SIZE PAGE_SIZE -#define LUO_FDT_KHO_ENTRY_NAME "LUO" -#define LUO_FDT_COMPATIBLE "luo-v2" -#define LUO_FDT_ABI_HEADER "luo-abi-header" +#define LUO_KHO_ENTRY_NAME "LUO" +#define LUO_ABI_COMPATIBLE "luo-v3" +#define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8) =20 /** * struct luo_ser - Centralized LUO ABI header. + * @compatible: Compatibility string identifying the LUO ABI version. * @liveupdate_num: A counter tracking the number of successful live updat= es. * @sessions_pa: Physical address of the first session block header. * @flbs_pa: Physical address of the FLB header. * - * This structure is the root of all preserved LUO state. It is pointed to= by - * the "luo-abi-header" property in the LUO FDT. + * This structure is the root of all preserved LUO state. */ struct luo_ser { + char compatible[LUO_ABI_COMPAT_LEN]; u64 liveupdate_num; u64 sessions_pa; u64 flbs_pa; @@ -111,7 +96,7 @@ struct luo_ser { * @data: Private data * @token: User provided token for this file * - * If this structure is modified, LUO_SESSION_COMPATIBLE must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_file_ser { char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH]; @@ -142,7 +127,7 @@ struct luo_file_set_ser { * physical memory preserved across the kexec. It provides the necessary * metadata to interpret the array of session entries that follow. * - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_session_header_ser { u64 count; @@ -159,7 +144,7 @@ struct luo_session_header_ser { * session) is created and passed to the new kernel, allowing it to recons= truct * the session context. * - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_session_ser { char name[LIVEUPDATE_SESSION_NAME_LENGTH]; @@ -180,7 +165,7 @@ struct luo_session_ser { * This structure is located at the physical address specified by the * flbs_pa in luo_ser. * - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_flb_header_ser { u64 pgcnt; @@ -202,7 +187,7 @@ struct luo_flb_header_ser { * passed to the new kernel. Each entry allows the LUO core to restore one * global, shared object. * - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_flb_ser { char name[LIVEUPDATE_FLB_COMPAT_LENGTH]; diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index fbc18c5f4230..e261a03a1b47 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -63,8 +62,7 @@ =20 static struct { bool enabled; - void *fdt_out; - void *fdt_in; + struct luo_ser *luo_ser_out; u64 liveupdate_num; } luo_global; =20 @@ -81,11 +79,10 @@ early_param("liveupdate", early_liveupdate_param); =20 static int __init luo_early_startup(void) { + phys_addr_t luo_ser_phys; struct luo_ser *luo_ser; - int err, header_size; - phys_addr_t fdt_phys; - const void *ptr; - u64 luo_ser_pa; + size_t len; + int err; =20 if (!kho_is_enabled()) { if (liveupdate_enabled()) @@ -94,40 +91,29 @@ static int __init luo_early_startup(void) return 0; } =20 - /* Retrieve LUO subtree, and verify its format. */ - err =3D kho_retrieve_subtree(LUO_FDT_KHO_ENTRY_NAME, &fdt_phys, NULL); + /* Retrieve LUO state from KHO. */ + err =3D kho_retrieve_subtree(LUO_KHO_ENTRY_NAME, &luo_ser_phys, &len); if (err) { if (err !=3D -ENOENT) { - pr_err("failed to retrieve FDT '%s' from KHO: %pe\n", - LUO_FDT_KHO_ENTRY_NAME, ERR_PTR(err)); + pr_err("failed to retrieve LUO state '%s' from KHO: %pe\n", + LUO_KHO_ENTRY_NAME, ERR_PTR(err)); return err; } =20 return 0; } =20 - luo_global.fdt_in =3D phys_to_virt(fdt_phys); - err =3D fdt_node_check_compatible(luo_global.fdt_in, 0, - LUO_FDT_COMPATIBLE); - if (err) { - pr_err("FDT '%s' is incompatible with '%s' [%d]\n", - LUO_FDT_KHO_ENTRY_NAME, LUO_FDT_COMPATIBLE, err); - + if (len < sizeof(*luo_ser)) { + pr_err("LUO state is too small (%zu < %zu)\n", len, sizeof(*luo_ser)); return -EINVAL; } =20 - header_size =3D 0; - ptr =3D fdt_getprop(luo_global.fdt_in, 0, LUO_FDT_ABI_HEADER, &header_siz= e); - if (!ptr || header_size !=3D sizeof(u64)) { - pr_err("Unable to get ABI header '%s' [%d]\n", - LUO_FDT_ABI_HEADER, header_size); - + luo_ser =3D phys_to_virt(luo_ser_phys); + if (strncmp(luo_ser->compatible, LUO_ABI_COMPATIBLE, LUO_ABI_COMPAT_LEN))= { + pr_err("LUO state is incompatible with '%s'\n", LUO_ABI_COMPATIBLE); return -EINVAL; } =20 - luo_ser_pa =3D get_unaligned((u64 *)ptr); - luo_ser =3D phys_to_virt(luo_ser_pa); - luo_global.liveupdate_num =3D luo_ser->liveupdate_num; pr_info("Retrieved live update data, liveupdate number: %lld\n", luo_global.liveupdate_num); @@ -160,37 +146,20 @@ static int __init liveupdate_early_init(void) } early_initcall(liveupdate_early_init); =20 -/* Called during boot to create outgoing LUO fdt tree */ -static int __init luo_fdt_setup(void) +/* Called during boot to create outgoing LUO state */ +static int __init luo_state_setup(void) { struct luo_ser *luo_ser; - u64 luo_ser_pa; - void *fdt_out; int err; =20 - fdt_out =3D kho_alloc_preserve(LUO_FDT_SIZE); - if (IS_ERR(fdt_out)) { - pr_err("failed to allocate/preserve FDT memory\n"); - return PTR_ERR(fdt_out); - } - luo_ser =3D kho_alloc_preserve(sizeof(*luo_ser)); if (IS_ERR(luo_ser)) { - err =3D PTR_ERR(luo_ser); - goto exit_free_fdt; + pr_err("failed to allocate/preserve LUO state memory\n"); + return PTR_ERR(luo_ser); } - luo_ser_pa =3D virt_to_phys(luo_ser); - - err =3D fdt_create(fdt_out, LUO_FDT_SIZE); - err |=3D fdt_finish_reservemap(fdt_out); - err |=3D fdt_begin_node(fdt_out, ""); - err |=3D fdt_property_string(fdt_out, "compatible", LUO_FDT_COMPATIBLE); - err |=3D fdt_property(fdt_out, LUO_FDT_ABI_HEADER, &luo_ser_pa, - sizeof(luo_ser_pa)); - err |=3D fdt_end_node(fdt_out); - err |=3D fdt_finish(fdt_out); - if (err) - goto exit_free_luo_ser; + + strscpy(luo_ser->compatible, LUO_ABI_COMPATIBLE, sizeof(luo_ser->compatib= le)); + luo_ser->liveupdate_num =3D luo_global.liveupdate_num + 1; =20 err =3D luo_session_setup_outgoing(&luo_ser->sessions_pa); if (err) @@ -200,21 +169,17 @@ static int __init luo_fdt_setup(void) if (err) goto exit_free_luo_ser; =20 - luo_ser->liveupdate_num =3D luo_global.liveupdate_num + 1; - - err =3D kho_add_subtree(LUO_FDT_KHO_ENTRY_NAME, fdt_out, - fdt_totalsize(fdt_out)); + err =3D kho_add_subtree(LUO_KHO_ENTRY_NAME, luo_ser, sizeof(*luo_ser)); if (err) goto exit_free_luo_ser; - luo_global.fdt_out =3D fdt_out; + + luo_global.luo_ser_out =3D luo_ser; =20 return 0; =20 exit_free_luo_ser: kho_unpreserve_free(luo_ser); -exit_free_fdt: - kho_unpreserve_free(fdt_out); - pr_err("failed to prepare LUO FDT: %d\n", err); + pr_err("failed to prepare LUO state: %d\n", err); =20 return err; } @@ -230,7 +195,7 @@ static int __init luo_late_startup(void) if (!liveupdate_enabled()) return 0; =20 - err =3D luo_fdt_setup(); + err =3D luo_state_setup(); if (err) luo_global.enabled =3D false; =20 --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f175.google.com (mail-qk1-f175.google.com [209.85.222.175]) (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 205D2375ADD for ; Sat, 30 May 2026 22:19:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179595; cv=none; b=uKQGSwXKwHHbbdJ+D7Rzgw3P3oPfXxuc223GEaSp2UR9L9CEzMNoagSL1LhUmFzMzXc49PNtWb/V0mpyNbFBTaHW4maMw7Ctvh9wxU+SrOBnhaUyBtfmXUoQC6xkCs98FcVViUznKGeAjp3S12wyXeWESIXAPvJa3JOeB3Quyag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179595; c=relaxed/simple; bh=bhQWLj7PPI9UClPVVfb3CJJP1nHiv+tJKCbUyOi+1+A=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PWpLCLm1HdnPfNarUpWmZPnusiSllY6ZJJempH3DNo9+jkXZUmKOv9X2mXwSrnI4Aif7z6lSaBQu9XsBSX7dx9EyTLEElX1EXYlI89QFqzdB1saRS1jd/ot+XpUcEuSzjPb+guIi0QbQmJfEAwx1MSC62g7Zua4Kiiz4ToQYZs0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=B+cCay2m; arc=none smtp.client-ip=209.85.222.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="B+cCay2m" Received: by mail-qk1-f175.google.com with SMTP id af79cd13be357-914bfa75911so948812285a.1 for ; Sat, 30 May 2026 15:19:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179593; x=1780784393; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=M0UeBGKKNpBDiXtsHx+XK9ecjuYaKOuvdeJHksP7ylQ=; b=B+cCay2mH6PBBLqoGu+xg01ymvomz2Tj48fXNn2ZFptH6Hz6gjg8MbSHIq+BP0zId0 KCyh/Kyo7Rw+K1FDSyjtY/wd3O3hOSWYkpu/aXVpq7hkiFd+zCcVEexRSQZOFH2rda4X 9hx8eZNKmLyafLJdjgfsZv328I0B9a7TGlHwcMZ2pcrgB4cgDpfkdexSzxmzFVxoXo2s 2pHmWf3oeGdOcbUZtTC2ERFXKMWbJ8OqbSGVKSfISoRQDYiRWXTRYMU/UO2L39FEGyrK xPvDA8pKtVH7NfuZXAeQU/oJ5ZwPn56y7NQVyUSZUUcySWgdLv/SUDNs8USLS4scofKg gAbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179593; x=1780784393; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=M0UeBGKKNpBDiXtsHx+XK9ecjuYaKOuvdeJHksP7ylQ=; b=iXAXiZhBug65Hs3Ehf9CjXHP43nYw3NjunotBblSldP/JUoQCebwYLhOcw5GWFvoIR sSRi+5fJ/ZUCG4g/nTXWat8KFdDSXkffs08NOSupQmdMhaSUpn1N1a/Kj+c9K7JxvZpj BqYtZ2cndUPGvYTjKb076hxeLujDSMhoMcPXtP06gIHcQen9Xo4BywRPzHbKpmfLKqtl P/t/4eXqFV8U3ItfVjkp/G0C/pf6AaaIkg1iIhznoPlnKTn+jNpwhZ5TzTY16LdKyc9c WhMuRI1nVa+A8JoLh0+DwImjHhDV9fSutInEJpMyD/VHVVfN8s3w6fGWicZ3hikWrHIw WC/Q== X-Forwarded-Encrypted: i=1; AFNElJ+Tp5u1TV2R5Rzly+AZ/T7a3Vipxs5fhyCozCuqcp+2+IZzO1lmDTrgZijH7YRJqfI7yfkUP4WGG73S7GY=@vger.kernel.org X-Gm-Message-State: AOJu0YxRkiCH4ceQk/4YMwLjI0oOINYS10Cjt+H2j3cF2FI/y99xL5XW NoROs2jc3Ba/4vcNRgYHuNlR7A7Bb3sfPuk4WKY5ngkjcSmNpMEO3h9zKkxdoRvxtu4= X-Gm-Gg: Acq92OELLo3AgxFHWo0/XL8FQKyBtiMMpZDE91zBPXHtfR5RpqjmqY73f2e86A3qi5N tswXvqlMqbh1ZwNBuQXxXMi7EE4OjmfOlz7u+x15AWiv9ZRWtHSAO26AdCVydQaT/SziHBL/+U5 hXU7CRfnwX65vGmsKVUfOb9+x7HfThkyPCFa7MAtILHZVQ+YG8Z60CKV8zzAoGQRSo0lzIsG9UP S8pW/iqmKQLCXS1N2jSSxw0MNX6wsUI3Au9JPFaxOBUs9MyGFwJ0lZyX+j2y8W7KcTOwe3Aj1ry kTRLiwtY/NNqaViaH4ryDzH/IC7XKAeytKtWsNLFtJ0ojWwrDVC3G2PEJptkuAcaOb0NvAcKL1i Gicn67xLVYEz0o7pPliWSAVosrEFVx9jv0fNqWDdmaTDySmetn6DwlHoLvGr40UXxBRlXbJzL6j ZN7kBHSgMK0cfYacAyN0wIPcs+vXvfh4/lN3Dm3rfx3nTEcTBioI6OB7gJVBwqGsmA4Vh4+puD X-Received: by 2002:a05:620a:2697:b0:914:b4c3:997b with SMTP id af79cd13be357-9153decd84bmr587250885a.1.1780179593182; Sat, 30 May 2026 15:19:53 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:52 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 05/13] liveupdate: Extract luo_file_deserialize_one helper Date: Sat, 30 May 2026 22:19:30 +0000 Message-ID: <20260530221938.115978-6-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extract the logic for deserializing single entries for files into separate helper functions. In preparation to a linked-block serialization for files. This is a pure code movement, no other changes intended. Acked-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav (Google) Signed-off-by: Pasha Tatashin --- kernel/liveupdate/luo_file.c | 77 ++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index 208987502f73..9eec07a9e9fc 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -753,6 +753,46 @@ int luo_file_finish(struct luo_file_set *file_set) return 0; } =20 +static int luo_file_deserialize_one(struct luo_file_set *file_set, + struct luo_file_ser *ser) +{ + struct liveupdate_file_handler *fh; + bool handler_found =3D false; + struct luo_file *luo_file; + + down_read(&luo_register_rwlock); + list_private_for_each_entry(fh, &luo_file_handler_list, list) { + if (!strcmp(fh->compatible, ser->compatible)) { + if (try_module_get(fh->ops->owner)) + handler_found =3D true; + break; + } + } + up_read(&luo_register_rwlock); + + if (!handler_found) { + pr_warn("No registered handler for compatible '%.*s'\n", + (int)sizeof(ser->compatible), + ser->compatible); + return -ENOENT; + } + + luo_file =3D kzalloc_obj(*luo_file); + if (!luo_file) { + module_put(fh->ops->owner); + return -ENOMEM; + } + + luo_file->fh =3D fh; + luo_file->file =3D NULL; + luo_file->serialized_data =3D ser->data; + luo_file->token =3D ser->token; + mutex_init(&luo_file->mutex); + list_add_tail(&luo_file->list, &file_set->files_list); + + return 0; +} + /** * luo_file_deserialize - Reconstructs the list of preserved files in the = new kernel. * @file_set: The incoming file_set to fill with deserialized data. @@ -782,6 +822,7 @@ int luo_file_deserialize(struct luo_file_set *file_set, struct luo_file_set_ser *file_set_ser) { struct luo_file_ser *file_ser; + int err; u64 i; =20 if (!file_set_ser->files) { @@ -809,39 +850,9 @@ int luo_file_deserialize(struct luo_file_set *file_set, */ file_ser =3D file_set->files; for (i =3D 0; i < file_set->count; i++) { - struct liveupdate_file_handler *fh; - bool handler_found =3D false; - struct luo_file *luo_file; - - down_read(&luo_register_rwlock); - list_private_for_each_entry(fh, &luo_file_handler_list, list) { - if (!strcmp(fh->compatible, file_ser[i].compatible)) { - if (try_module_get(fh->ops->owner)) - handler_found =3D true; - break; - } - } - up_read(&luo_register_rwlock); - - if (!handler_found) { - pr_warn("No registered handler for compatible '%.*s'\n", - (int)sizeof(file_ser[i].compatible), - file_ser[i].compatible); - return -ENOENT; - } - - luo_file =3D kzalloc_obj(*luo_file); - if (!luo_file) { - module_put(fh->ops->owner); - return -ENOMEM; - } - - luo_file->fh =3D fh; - luo_file->file =3D NULL; - luo_file->serialized_data =3D file_ser[i].data; - luo_file->token =3D file_ser[i].token; - mutex_init(&luo_file->mutex); - list_add_tail(&luo_file->list, &file_set->files_list); + err =3D luo_file_deserialize_one(file_set, &file_ser[i]); + if (err) + return err; } =20 return 0; --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (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 51980378833 for ; Sat, 30 May 2026 22:19:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179596; cv=none; b=jtuPlcOuxrTcQF8AoLPhze0y000y29mB0be4TvqCDd7WCqww9e+NSCDdoiBcZZiiHKGZlu7NUzdeEv8Oo9q8sMcCvbbO2VlqgLA8RdXT5TkCwSwKJaAwWoZH5ku+6565waVbGcaftITRM7pqQOV4AKq0Pm8sC78kZm/0d4LUqsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179596; c=relaxed/simple; bh=PfkjUT85iG6ZEEiSWFVhFCj3d2qFujCbQIn6yvDet10=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l/31STYHbwjyo6GqKkmXLx5L7/O0hf70+R5yI7G/Zapag8X4Ry2cIIx+ptrBoxFuh2jXr4F2UrOluh1CkaRkMPWi7G6IK3ICCLGN4Y6AnxC1oYKJ3cR6D5pd/Ooz6Kguh0cL9pQnQ2Jb5qVbZtzCgm/fqbJR9NBuEs0270V9Jc4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=GlUcBfZ2; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="GlUcBfZ2" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-9154ca1aa1dso53043385a.0 for ; Sat, 30 May 2026 15:19:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179594; x=1780784394; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=WamWMdUBlghIACFozBjX6pZ6qu316jN4xzYIhWYXbwQ=; b=GlUcBfZ2lpiRZ+nyYGKM6icl5ONTnYnjkm308SlYiLtcRKcm2Y75mKs3hy0raZ62cT 8CH43YrMGMl6UHINfT9rFHhFTvHYYDoAOAMTwcCCMSDFLMeHZ4zAKeoiSGnIUaPPAd9y l7KJfG06hxlUX/fO0diTILKXI8oFA6ojG3Ib2PFrWFQ7jeqbXgKRj8J1FX9s3pBR8s9Y CmWaej2IhIAC9d9iF55qnoSwEzYrrQJyRJx9ITUociwISl04wL/aCmUhVn9ptcZlDWgf zrTWaYVyjgMWCoHUZKtiVif7fozngwP83nz/MSFfelTpM0NwKdXHuzzrvpjZbFTweEYg Ce7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179594; x=1780784394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=WamWMdUBlghIACFozBjX6pZ6qu316jN4xzYIhWYXbwQ=; b=jrFjRDvxAc+pFm4V67j5OvVJEaQU/ywm43r+dJoL4Sysi3TUAfKLDGBRYnmSqwurDd g0okuTETq2GNGdsER8hqtC+3CWq8wnvCEvXC8jiN5v7ALNLAXOeqjPcbgTKNTvI5Otj2 84bfaswF5G1JdstBSKPUp2d/eP24ilx72zghQX4TPDuj0I1W4VHylJs0tgG6LNWVlq1l WCi/gD2jdEBPkp4bVRoCMaRHMxNtAf6dq7tiQflFi1rptcKw2hqwSHN7BE45bSo+QMGA IJUL319f+e5g9VSt2PYX8azeMFUZ9IxdqXh4s4VcTClTzlpe8UfYCQBRrfSEtqOcYUzM VkCQ== X-Forwarded-Encrypted: i=1; AFNElJ8RGkyXtfLMKZbQAhrCHUSppnRxoWZGlucrs88bv407M1EWniRU0iDrNteNMiOXB+zpDdeVyzSejsMDBOQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyLjY9LHuDHH+UUURvH22xKoMmd4CKm4cOlb1fZgH4Z5kqGMJOr iAyAiuAtluLIpk75m5i3ATjPAqK8VAPBBaNGdAFyVnY7V1mpv9x+mgHGr9WaUpEteh0= X-Gm-Gg: Acq92OFnrRifZPs/wfkjw7BMy0qnCVJBIAgVsnk09AAlmh8tAmVRHphXnlp+ossb6e/ F2El4/bi4R5CM1oRNHYW2jdzGlAZE6X2jFroqZlEXNY8b9HbGqLk4V8/3PM4t5xlNznR8ES80le 4HCZO0H0P/pd4jZ3WapSRVShlBo2u4AqPgr446sV9v+mAadklx9lR5A+v2ATUDcmQwhPCqH+6AA VI101vofDQi+1hMYNmXRFPKmIR25HYvrTS0WvtUpa+3BMda/4pFUXq22wpbFYm2882nOf9wyJvx bW8mY17tklsQGgmKaFG2QO/4m78XzB+c3pSzSUJpBsNkaaHXUeaX7Im83f1KizSTS+Mv872jEIy 3xQz3j73a+xeSpAvF9Hgfvu7faqS2fka4GlvhrxXSfL56JsVZER6p3WIRqtN/rIqa1660IkwR/w Ltn0bVBQWPYa8e/ZoTtLokT+KQmUECn/SNjYHL87V9JizoiwutZZ5S0djTNUgc4w== X-Received: by 2002:a05:620a:198e:b0:8d6:6db0:88de with SMTP id af79cd13be357-9152fa4cdfdmr980466785a.44.1780179594396; Sat, 30 May 2026 15:19:54 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:53 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 06/13] liveupdate: Extract luo_session_deserialize_one helper Date: Sat, 30 May 2026 22:19:31 +0000 Message-ID: <20260530221938.115978-7-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extract the logic for deserializing single entries for sessions into separate helper functions. In preparation to a linked-block serialization for sessions. This is a pure code movement, no other changes intended. Acked-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav (Google) Signed-off-by: Pasha Tatashin --- kernel/liveupdate/luo_session.c | 62 +++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index 3b760fefa7b9..b728fd9e3ed2 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -525,6 +525,40 @@ int __init luo_session_setup_incoming(u64 sessions_pa) return 0; } =20 +static int luo_session_deserialize_one(struct luo_session_header *sh, + struct luo_session_ser *ser) +{ + struct luo_session *session; + int err; + + session =3D luo_session_alloc(ser->name); + if (IS_ERR(session)) { + pr_warn("Failed to allocate session [%.*s] during deserialization %pe\n", + (int)sizeof(ser->name), ser->name, session); + return PTR_ERR(session); + } + + err =3D luo_session_insert(sh, session); + if (err) { + pr_warn("Failed to insert session [%s] %pe\n", + session->name, ERR_PTR(err)); + luo_session_free(session); + return err; + } + + scoped_guard(mutex, &session->mutex) { + err =3D luo_file_deserialize(&session->file_set, + &ser->file_set_ser); + } + if (err) { + pr_warn("Failed to deserialize files for session [%s] %pe\n", + session->name, ERR_PTR(err)); + return err; + } + + return 0; +} + int luo_session_deserialize(void) { struct luo_session_header *sh =3D &luo_session_global.incoming; @@ -555,33 +589,9 @@ int luo_session_deserialize(void) * reliably reset devices and reclaim memory. */ for (int i =3D 0; i < sh->header_ser->count; i++) { - struct luo_session *session; - - session =3D luo_session_alloc(sh->ser[i].name); - if (IS_ERR(session)) { - pr_warn("Failed to allocate session [%.*s] during deserialization %pe\n= ", - (int)sizeof(sh->ser[i].name), - sh->ser[i].name, session); - return PTR_ERR(session); - } - - err =3D luo_session_insert(sh, session); - if (err) { - pr_warn("Failed to insert session [%s] %pe\n", - session->name, ERR_PTR(err)); - luo_session_free(session); - return err; - } - - scoped_guard(mutex, &session->mutex) { - err =3D luo_file_deserialize(&session->file_set, - &sh->ser[i].file_set_ser); - } - if (err) { - pr_warn("Failed to deserialize files for session [%s] %pe\n", - session->name, ERR_PTR(err)); + err =3D luo_session_deserialize_one(sh, &sh->ser[i]); + if (err) return err; - } } =20 kho_restore_free(sh->header_ser); --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f169.google.com (mail-qk1-f169.google.com [209.85.222.169]) (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 22FBE3793CE for ; Sat, 30 May 2026 22:19:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179605; cv=none; b=VwG6QJnf6YuYzh2095zi81Z4GglSfnC2/dJ4Pix0Ou4R+HnF0I/YYbUIbU3CKpkwypcT+aiI/kjyavFmDLFzZBPK8jNLP8oXfwF5b1lXm11fgGlJ33gO3s3w0HGV1ip1Rj2PIKsLy4tNmU4/gbtwYnkfobQLI8t1dJVwEccp4Lk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179605; c=relaxed/simple; bh=HDcQp9Z7J2wi3tm6hLiETjAXtjbO7bfEWuhqu+mSdqk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JNPuvaEL8Ny2ylKkUPePzb/hap3G7OXNuWDaKrwlA0HVhiGqL6RJqCh34ktnXj1VtTGkhDe9+SzE+ePXAIpqVi352vjAAziWzSENcT3lVPxmGOD71OInUryy8W2YqgodaD+WHaRXrDkqSeFof1EUW1ifJ5m5XRdRBq4DAUQ/Leg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=Vf1a4vmF; arc=none smtp.client-ip=209.85.222.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="Vf1a4vmF" Received: by mail-qk1-f169.google.com with SMTP id af79cd13be357-914a90b69a3so1047706385a.3 for ; Sat, 30 May 2026 15:19:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179597; x=1780784397; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=9ZjBjxh8DW5cjLIflwRa7qLckFdwcn3zUMIzIhrdvTY=; b=Vf1a4vmFtBOvX7/pOtbt7apCRyjlJDbUaGDIaRcsBRfJP4sWyT2pWwwhvvVP+w+odk BtZImYKvLNOKsq+XtL1VFxIECFV+4cxMfe2FT/WntW7gZ7f4rqCqeaZLXrOvZ1oth8R4 qjJ40hpMMU3a3vGi8sLl85QgoBttelPlmazwJJtuK8MxIh8bLfHWiUtj/9BRQtkCQ3/3 9ubH4SDpjYKOqM7/4lTLMjmj448Ws8eHGUgxoZmqgZK/gippiZA7NGRP/vMibyQD9GP4 1E31jGaKiFkVeiEyFkcZN8+lpZNW6k3jYCHcYDhav23lo2tf1H9yk49we81qY9HtiETL ixAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179597; x=1780784397; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=9ZjBjxh8DW5cjLIflwRa7qLckFdwcn3zUMIzIhrdvTY=; b=C0rolqM8YVMa5i917Z5632GKL72DYYVkncpb2Un2C9bZkqBDHLakZ9PJ8TOzP6Gf7P Zy9aFhZ3uMpB5U0iNfMEJAFpyKlWv25Mnbdog5IwX7NNQLpGR+wT/w+FPwJ7eQ3DA9yr vyDa0yptYYLzHP6zs4/IvW8iQnc9/P2a15rx0eW1/3JgMvGjClMmwVer7nG0nm2AAf6f xApFcD3rz1OF+AWKvk3wvRXSV20LTymzoVtOy7G9qR18uMNydW+xQCyTzwVCIl9Rfzv6 MQDQbO7OmH6X39+Ub6Fk4/ni+oA6n8nkh9Wi4ErqNqf/Tq6Gq3YKWzan9npKRS1ihnFb znBw== X-Forwarded-Encrypted: i=1; AFNElJ9ZuRgIWsPxnXBxWkYmFbOrFRCr1ZqcYOJxlq4634MDiBvw7ZotOZswKN4pm6g1umqFMK039GaPPP1tdE4=@vger.kernel.org X-Gm-Message-State: AOJu0YzN0h3cBbtu1Kk8gwtk6GE2yy07W0XKLGF1fhHDJ+fHB7ojtMS3 dSjP1HtVqca7+vL/4z9dGqW6C/eIiyHujX71zuG+sG9vr4tc43S13R/MkmoXab5vM7Y= X-Gm-Gg: Acq92OHzX1xk5zvpunnljVRlvUdrbpgf2Xd8Ual7FRD0rYGtiAtmzPhDgfB+CEzQYwW Vwtm1dzDBPlhbpkQi1/1DABBrt+Y90v6t6Cwdx1EnV0J7v80BZvbgA7A/Tr5EkVS6JWCF8CkubJ kEhhlGIfbAANjjM4l9ArEWpUnqYj5ukyqD0AILGWMPbPuMKn5XqBiROv8leMVmIN3e6k5ZAE3Op O614sI9eAuOm74+wZPqjQ4S91pNziPYwMTPXj18p7Vs7yQGU1xX8HzbbrPIIGXzxd5aAv9j9NQS djafOZiB7tKd1VLzLeJlSS7yW38ir4EJzmOFR6ya86nPPkRB0zhFStLdQ4FMh6HmKO0MMxWSuyI hgL6J6fIKOocCig2r4fojgfOzYRw6wCZFuff1GOGy3f59rf6arnwv6L/Sd9+VAorzzZOfbklFT8 ibeRTH09EGwd86mzdn6SCpxij00OtgawrdYjfgCmVNfNONyv2zSP9P/MECz7rg2TNPj3zRoJb9 X-Received: by 2002:a05:620a:a409:20b0:915:4256:9219 with SMTP id af79cd13be357-915425692c1mr413523785a.36.1780179597003; Sat, 30 May 2026 15:19:57 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:55 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 07/13] kho: add support for linked-block serialization Date: Sat, 30 May 2026 22:19:32 +0000 Message-ID: <20260530221938.115978-8-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a linked-block serialization mechanism for state handover. Previously, LUO used contiguous memory blocks for serializing sessions and files, which imposed limits on the total number of items that could be preserved across a live update. This commit adds the infrastructure for a more flexible, block-based approach where serialized data is stored in a chain of linked blocks. This is a generic KHO serialization block infrastructure that can be used by multiple subsystems. Signed-off-by: Pasha Tatashin --- Documentation/core-api/kho/abi.rst | 5 + Documentation/core-api/kho/index.rst | 11 + MAINTAINERS | 1 + include/linux/kho/abi/block.h | 56 ++++ include/linux/kho_block.h | 79 ++++++ kernel/liveupdate/Makefile | 1 + kernel/liveupdate/kho_block.c | 384 +++++++++++++++++++++++++++ 7 files changed, 537 insertions(+) create mode 100644 include/linux/kho/abi/block.h create mode 100644 include/linux/kho_block.h create mode 100644 kernel/liveupdate/kho_block.c diff --git a/Documentation/core-api/kho/abi.rst b/Documentation/core-api/kh= o/abi.rst index 799d743105a6..edeb5b311963 100644 --- a/Documentation/core-api/kho/abi.rst +++ b/Documentation/core-api/kho/abi.rst @@ -28,6 +28,11 @@ KHO persistent memory tracker ABI .. kernel-doc:: include/linux/kho/abi/kexec_handover.h :doc: KHO persistent memory tracker =20 +KHO serialization block ABI +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D + +.. kernel-doc:: include/linux/kho/abi/block.h + See Also =3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/Documentation/core-api/kho/index.rst b/Documentation/core-api/= kho/index.rst index 0a2dee4f8e7d..320914a42178 100644 --- a/Documentation/core-api/kho/index.rst +++ b/Documentation/core-api/kho/index.rst @@ -83,6 +83,17 @@ Public API .. kernel-doc:: kernel/liveupdate/kexec_handover.c :export: =20 +KHO Serialization Blocks API +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +.. kernel-doc:: kernel/liveupdate/kho_block.c + :doc: KHO Serialization Blocks + +.. kernel-doc:: include/linux/kho_block.h + +.. kernel-doc:: kernel/liveupdate/kho_block.c + :internal: + See Also =3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/MAINTAINERS b/MAINTAINERS index 2fb1c75afd16..fd119b343e99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14194,6 +14194,7 @@ F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h F: include/linux/kho/ +F: include/linux/kho_block.h F: kernel/liveupdate/kexec_handover* F: lib/test_kho.c F: tools/testing/selftests/kho/ diff --git a/include/linux/kho/abi/block.h b/include/linux/kho/abi/block.h new file mode 100644 index 000000000000..8641c20b379b --- /dev/null +++ b/include/linux/kho/abi/block.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin + */ + +/** + * DOC: KHO Serialization Blocks ABI + * + * Subsystems using the KHO Serialization Blocks framework rely on the sta= ble + * Application Binary Interface defined below to pass serialized state fro= m a + * pre-update kernel to a post-update kernel. + * + * This interface is a contract. Any modification to the structure fields, + * compatible strings, or the layout of the `__packed` serialization + * structures defined here constitutes a breaking change. Such changes req= uire + * incrementing the version number in the `KHO_BLOCK_ABI_COMPATIBLE` strin= g to + * prevent a new kernel from misinterpreting data from an old kernel. + * + * Changes are allowed provided the compatibility version is incremented; + * however, backward/forward compatibility is only guaranteed for kernels + * supporting the same ABI version. + */ + +#ifndef _LINUX_KHO_ABI_BLOCK_H +#define _LINUX_KHO_ABI_BLOCK_H + +#include +#include + +#define KHO_BLOCK_ABI_COMPATIBLE "kho-block-v1" + +/** + * KHO_BLOCK_SIZE - The size of each serialization block. + * + * This is defined as PAGE_SIZE. PAGE_SIZE is ABI compliant because live + * update between kernels with different page sizes is not supported by KH= O. + */ +#define KHO_BLOCK_SIZE PAGE_SIZE + +/** + * struct kho_block_header_ser - Header for the serialized data block. + * @next: Physical address of the next struct kho_block_header_ser. + * @count: The number of entries that immediately follow this header in the + * memory block. + * + * This structure is located at the beginning of a block of physical memory + * preserved across a kexec. It provides the necessary metadata to interpr= et + * the array of entries that follow. + */ +struct kho_block_header_ser { + u64 next; + u64 count; +} __packed; + +#endif /* _LINUX_KHO_ABI_BLOCK_H */ diff --git a/include/linux/kho_block.h b/include/linux/kho_block.h new file mode 100644 index 000000000000..5e6b87b1befa --- /dev/null +++ b/include/linux/kho_block.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin + */ + +#ifndef _LINUX_KHO_BLOCK_H +#define _LINUX_KHO_BLOCK_H + +#include +#include +#include + +/** + * struct kho_block - Internal representation of a serialization block. + * @list: List head for linking blocks in memory. + * @ser: Pointer to the serialized header in preserved memory. + */ +struct kho_block { + struct list_head list; + struct kho_block_header_ser *ser; +}; + +/** + * struct kho_block_set - A set of blocks that belong to the same object. + * @blocks: The list of serialization blocks (struct kho_block). + * @nblocks: The number of allocated serialization blocks. + * @head_pa: Physical address of the first block header. + * @entry_size: The size of each entry in the blocks. + * @count_per_block: The maximum number of entries each block can hold. + * @incoming: True if this block set was restored from the previous= kernel. + */ +struct kho_block_set { + struct list_head blocks; + long nblocks; + u64 head_pa; + size_t entry_size; + u64 count_per_block; + bool incoming; +}; + +/** + * struct kho_block_it - Iterator for serializing entries into blocks. + * @bs: The block set being iterated. + * @block: The current block. + * @i: The current entry index within @block. + */ +struct kho_block_it { + struct kho_block_set *bs; + struct kho_block *block; + u64 i; +}; + +/** + * KHO_BLOCK_SET_INIT - Initialize a static kho_block_set. + * @_name: Name of the kho_block_set variable. + * @_entry_size: The size of each entry in the block set. + */ +#define KHO_BLOCK_SET_INIT(_name, _entry_size) { \ + .blocks =3D LIST_HEAD_INIT((_name).blocks), \ + .entry_size =3D _entry_size, \ +} + +void kho_block_set_init(struct kho_block_set *bs, size_t entry_size); + +int kho_block_grow(struct kho_block_set *bs, u64 count); +void kho_block_shrink(struct kho_block_set *bs, u64 count); + +int kho_block_restore(struct kho_block_set *bs, u64 head_pa); +void kho_block_destroy(struct kho_block_set *bs); +void kho_block_set_clear(struct kho_block_set *bs); + +void kho_block_it_init(struct kho_block_it *it, struct kho_block_set *bs); +void *kho_block_it_next(struct kho_block_it *it); +void *kho_block_it_read(struct kho_block_it *it); +void *kho_block_it_prev(struct kho_block_it *it); +void kho_block_it_finalize(struct kho_block_it *it); + +#endif /* _LINUX_KHO_BLOCK_H */ diff --git a/kernel/liveupdate/Makefile b/kernel/liveupdate/Makefile index d2f779cbe279..eec9d3ae07eb 100644 --- a/kernel/liveupdate/Makefile +++ b/kernel/liveupdate/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 =20 luo-y :=3D \ + kho_block.o \ luo_core.o \ luo_file.o \ luo_flb.o \ diff --git a/kernel/liveupdate/kho_block.c b/kernel/liveupdate/kho_block.c new file mode 100644 index 000000000000..a4e650af946f --- /dev/null +++ b/kernel/liveupdate/kho_block.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin + */ + +/** + * DOC: KHO Serialization Blocks + * + * KHO provides a mechanism to preserve stateful data across a kexec hando= ver + * by serializing it into memory blocks. This file provides the common + * infrastructure for managing these blocks. + * + * Each block consists of a header (struct kho_block_header_ser) followed = by an + * array of serialized entries. Multiple blocks are linked together via a + * physical pointer in the header, forming a linked list that can be easily + * traversed in both the current and the next kernel. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + +/* + * Safeguard limit for the number of serialization blocks. This is used to + * prevent infinite loops and excessive memory allocation in case of memory + * corruption in the preserved state. + */ +#define KHO_MAX_BLOCKS 10000 + +/** + * kho_block_set_init - Initialize a block set. + * @bs: The block set to initialize. + * @entry_size: The size of each entry in the blocks. + */ +void kho_block_set_init(struct kho_block_set *bs, size_t entry_size) +{ + *bs =3D (struct kho_block_set)KHO_BLOCK_SET_INIT(*bs, entry_size); +} + +static inline u64 kho_block_count_per_block(struct kho_block_set *bs) +{ + if (unlikely(!bs->count_per_block)) { + bs->count_per_block =3D (KHO_BLOCK_SIZE - + sizeof(struct kho_block_header_ser)) / + bs->entry_size; + WARN_ON(!bs->count_per_block); + } + return bs->count_per_block; +} + +/* Free serialized data */ +static void kho_block_free_ser(struct kho_block_set *bs, + struct kho_block_header_ser *ser) +{ + if (bs->incoming) + kho_restore_free(ser); + else + kho_unpreserve_free(ser); +} + +static struct kho_block_header_ser *kho_block_alloc_ser(struct kho_block_s= et *bs) +{ + WARN_ON(bs->incoming); + return kho_alloc_preserve(KHO_BLOCK_SIZE); +} + +static int kho_block_add(struct kho_block_set *bs, + struct kho_block_header_ser *ser) +{ + struct kho_block *block, *last; + + if (bs->nblocks >=3D KHO_MAX_BLOCKS) + return -ENOSPC; + + block =3D kzalloc_obj(*block); + if (!block) + return -ENOMEM; + + block->ser =3D ser; + last =3D list_last_entry_or_null(&bs->blocks, struct kho_block, list); + list_add_tail(&block->list, &bs->blocks); + bs->nblocks++; + + if (last) + last->ser->next =3D virt_to_phys(ser); + else + bs->head_pa =3D virt_to_phys(ser); + + return 0; +} + +/** + * kho_block_grow - Create a new block if the current capacity is reached. + * @bs: The block set. + * @count: The current number of entries. + * + * This function handles the dynamic expansion of a block set. It allocates + * and links a new serialization block if the provided entry count matches + * the current total capacity of the set. + * + * Return: 0 on success, or a negative errno on failure. + */ +int kho_block_grow(struct kho_block_set *bs, u64 count) +{ + struct kho_block_header_ser *ser; + int err; + + if (WARN_ON(bs->incoming)) + return -EINVAL; + + if (count !=3D bs->nblocks * kho_block_count_per_block(bs)) + return 0; + + ser =3D kho_block_alloc_ser(bs); + if (IS_ERR(ser)) + return PTR_ERR(ser); + + err =3D kho_block_add(bs, ser); + if (err) { + kho_block_free_ser(bs, ser); + return err; + } + + return 0; +} + +/** + * kho_block_shrink - Conditionally destroy the last block in a block set. + * @bs: The block set. + * @count: The current number of entries across all blocks. + * + * This function checks if the last block in the set is redundant based on= the + * total entry count and the capacity of the preceding blocks. If the entry + * count can be accommodated by the blocks that come before the last one, = the + * last block is destroyed and removed from the set. + */ +void kho_block_shrink(struct kho_block_set *bs, u64 count) +{ + struct kho_block *last, *new_last; + + if (count > (bs->nblocks - 1) * kho_block_count_per_block(bs)) + return; + + if (list_empty(&bs->blocks)) + return; + + last =3D list_last_entry(&bs->blocks, struct kho_block, list); + list_del(&last->list); + bs->nblocks--; + kho_block_free_ser(bs, last->ser); + kfree(last); + + new_last =3D list_last_entry_or_null(&bs->blocks, struct kho_block, list); + if (new_last) + new_last->ser->next =3D 0; + else + bs->head_pa =3D 0; +} + +/* + * kho_cyclic_blocks_check - Check for cycles in a linked list of blocks. + * Uses Floyd's cycle-finding algorithm to ensure sanity of the incoming l= ist. + */ +static bool kho_cyclic_blocks_check(struct kho_block_set *bs) +{ + struct kho_block_header_ser *fast; + struct kho_block_header_ser *slow; + int count =3D 0; + + fast =3D phys_to_virt(bs->head_pa); + slow =3D fast; + + while (fast) { + if (count++ >=3D KHO_MAX_BLOCKS) { + pr_err("Linked list too long\n"); + return false; + } + + if (!fast->next) + break; + + fast =3D phys_to_virt(fast->next); + if (!fast->next) + break; + + fast =3D phys_to_virt(fast->next); + slow =3D phys_to_virt(slow->next); + + if (slow =3D=3D fast) { + pr_err("Cyclic list detected\n"); + return false; + } + } + + return true; +} + +/** + * kho_block_restore - Restore a block set from a physical address. + * @bs: The block set to restore. + * @head_pa: Physical address of the first block header. + * + * Return: 0 on success, or a negative errno on failure. + */ +int kho_block_restore(struct kho_block_set *bs, u64 head_pa) +{ + struct kho_block_header_ser *ser; + u64 next_pa =3D head_pa; + int err; + + /* Restored block sets use size from the previous kernel */ + bs->incoming =3D true; + if (!head_pa) + return 0; + + bs->head_pa =3D head_pa; + if (!kho_cyclic_blocks_check(bs)) { + bs->head_pa =3D 0; + return -EINVAL; + } + + while (next_pa) { + ser =3D phys_to_virt(next_pa); + if (ser->count > kho_block_count_per_block(bs)) { + pr_warn("Block contains too many entries: %llu\n", + ser->count); + err =3D -EINVAL; + goto err_destroy; + } + err =3D kho_block_add(bs, ser); + if (err) + goto err_destroy; + next_pa =3D ser->next; + } + + return 0; + +err_destroy: + kho_block_destroy(bs); + return err; +} + +/** + * kho_block_destroy - Destroy all blocks in a block set. + * @bs: The block set. + */ +void kho_block_destroy(struct kho_block_set *bs) +{ + u64 head_pa =3D bs->head_pa; + struct kho_block *block; + + while (!list_empty(&bs->blocks)) { + block =3D list_first_entry(&bs->blocks, struct kho_block, list); + list_del(&block->list); + kfree(block); + } + bs->nblocks =3D 0; + bs->head_pa =3D 0; + + while (head_pa) { + struct kho_block_header_ser *ser =3D phys_to_virt(head_pa); + + head_pa =3D ser->next; + kho_block_free_ser(bs, ser); + } +} + +/** + * kho_block_set_clear - Clear all serialized data in a block set. + * @bs: The block set to clear. + */ +void kho_block_set_clear(struct kho_block_set *bs) +{ + struct kho_block *block; + + list_for_each_entry(block, &bs->blocks, list) { + block->ser->count =3D 0; + memset(block->ser + 1, 0, KHO_BLOCK_SIZE - sizeof(*block->ser)); + } +} + +/** + * kho_block_it_init - Initialize a block set iterator. + * @it: The iterator to initialize. + * @bs: The block set to iterate over. + */ +void kho_block_it_init(struct kho_block_it *it, struct kho_block_set *bs) +{ + it->bs =3D bs; + it->block =3D list_first_entry_or_null(&bs->blocks, struct kho_block, lis= t); + it->i =3D 0; +} + +/** + * kho_block_it_next - Return the next entry slot in the block set. + * @it: The block iterator. + * + * If the current block is full, it automatically advances to the next blo= ck + * in the set. + * + * Return: A pointer to the next entry slot, or NULL if no more slots are + * available. + */ +void *kho_block_it_next(struct kho_block_it *it) +{ + if (!it->block) + return NULL; + + if (it->i =3D=3D kho_block_count_per_block(it->bs)) { + it->block->ser->count =3D it->i; + if (list_is_last(&it->block->list, &it->bs->blocks)) + return NULL; + it->block =3D list_next_entry(it->block, list); + it->i =3D 0; + } + + return (void *)(it->block->ser + 1) + (it->i++ * it->bs->entry_size); +} + +/** + * kho_block_it_read - Return the next entry slot for reading. + * @it: The block iterator. + * + * This function iterates through entries that were previously serialized, + * respecting the count stored in each block's header. + * + * Return: A pointer to the next entry slot, or NULL if no more entries are + * available. + */ +void *kho_block_it_read(struct kho_block_it *it) +{ + if (!it->block) + return NULL; + + while (it->i =3D=3D it->block->ser->count) { + if (list_is_last(&it->block->list, &it->bs->blocks)) + return NULL; + it->block =3D list_next_entry(it->block, list); + it->i =3D 0; + } + + return (void *)(it->block->ser + 1) + (it->i++ * it->bs->entry_size); +} + +/** + * kho_block_it_prev - Return the previous entry slot in the block set. + * @it: The block iterator. + * + * If the current index is at the start of a block, it automatically moves= to + * the end of the previous block. + * + * Return: A pointer to the previous entry slot, or NULL if at the very + * beginning of the block set. + */ +void *kho_block_it_prev(struct kho_block_it *it) +{ + if (!it->block) + return NULL; + + if (it->i =3D=3D 0) { + if (list_is_first(&it->block->list, &it->bs->blocks)) + return NULL; + it->block =3D list_prev_entry(it->block, list); + it->i =3D kho_block_count_per_block(it->bs); + } + + return (void *)(it->block->ser + 1) + (--it->i * it->bs->entry_size); +} + +/** + * kho_block_it_finalize - Finalize the current block by setting its entry= count. + * @it: The block iterator. + */ +void kho_block_it_finalize(struct kho_block_it *it) +{ + if (it->block) + it->block->ser->count =3D it->i; +} --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qv1-f45.google.com (mail-qv1-f45.google.com [209.85.219.45]) (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 31E3A366060 for ; Sat, 30 May 2026 22:19:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179604; cv=none; b=uxVpl1mWQfQNVLRTbhJ3auKBBf1mhXJS8GRsb7OgLz+aRtLWKc6bWvc1BAnoFKqrhZ/Uu5vwzp9MzheaAn/HcLxoYoxxE3GFW6gNi/qrOUp4E7/J6JoTs+pJQtYsJHSMcbJ+kge2XajG0ydrXFaehUeEoLzLhFTv4asEIO1d0pI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179604; c=relaxed/simple; bh=DhsdXZAIsYS+PKBWOqtIaOAZNzKcM4TBtkEe9giYrf8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=c1E4AWCDpgWPFiGsWefFfJzw29IbJ5mYbciJGkQxp6ECOiFP/vYWNI1Qi3M+zQAQiSb2qGg6vopUWQEPhJE3A3fLUkjHKQchLJaEF8hLZXt0Orem3ByKq7tCgVRp5U1anHED+wPTpgVAGbPLDxAwTAnPIU5x0PR34U8OWbwifNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=aaIDTUR7; arc=none smtp.client-ip=209.85.219.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="aaIDTUR7" Received: by mail-qv1-f45.google.com with SMTP id 6a1803df08f44-8ccdf8d4ac5so24959226d6.1 for ; Sat, 30 May 2026 15:19:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179598; x=1780784398; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/ssXPv2DRhDSGHaylMjR7rg2Io0bTsFx1rhCfXPl0Sk=; b=aaIDTUR7js6QH5ujnaXO28/RzUaN1AMy80q2HR5JoPT5hkCU9x3pIbUDDXXdISFv2d 81SBqgHmc27pXvQI/zcEFP1a60qGt/vcI2u3T5OHuNbliqmuKwFery1MfdCj0+M+ijY6 TQHQVuh+n2NL322WXnkMsCkonawC6nxAe7V1uluyTVfd1410jloHRuGmDLyW4oc9Jiqk rXYshjmVztGqhAaZM+Buz+jCgpZjVKjCh8UENzd/G48ngs8VX2ybUQwrKNedJcmV0iS2 HcEnrNgbVLQkmdA35wc03M5qI53iKaIk8bxRwp2k9LtDIuIFK2RlnlIg78BKZR86j66y FfCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179598; x=1780784398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=/ssXPv2DRhDSGHaylMjR7rg2Io0bTsFx1rhCfXPl0Sk=; b=emjEuaea7ZMA/koAgMMoCyI8wttj/fGaEgx7xDFaH0F6UWLTIwoPWlfkEZBkyR3+4w XntLlaQI4MPcKgD8P8LZf6KF5lq5EKKp+o0kGXQhGBrUXfIwXwyMhNB6eaePYs6bBN3k fvaOy5fDUwSekwrCRJ4Y8P45sDholCA3r8+c/xPTVCPct0iOi1EJG5fR4Hdy5996ZA02 ILMXtmedyIlCMRtLRxJLCcJj7CAK7pKMX1mndJGPrWy/GcH7BkFaMKODpT0AlC4XAiEe TmwyqEzdMthrGVigOapXsYQF+3wGraA0Att5eghdow48CBfXI+msPyFzAsaSFyHe3sLz i5Sg== X-Forwarded-Encrypted: i=1; AFNElJ+Qm4bAh8N9xazCZJ5oPrSrsOvt26K/d2Bf7jKw6oiX7W3Rqkf40fgZnrGRUnWLW8E3gjLaLul8+RUcf54=@vger.kernel.org X-Gm-Message-State: AOJu0YzfEA5gHWdLtwX2nSAVVFsh9n+WnuKupQDxjK12+oKD1b+LYkXv aent5irib9uaak5rfXdoY56P/glsm7XZ1i1ZZUEtFxUjZn0xXJjczWQBVxFBJUqnUW0= X-Gm-Gg: Acq92OHPKUJR0TmS01B6s6F050xTWgsFXvOGjXYpVzK8dbEBbaNScc6imwrvBNgoj3b r5gnonTaB5aQ7p2vkMUOAH4QA8IZnTknAA5Hqhq+MJADDePLxRu9+4CHUqNT55be3c6VJfOQ5Qt ShjIDGBFY6yqwbj3pIK4MT5cRPKjm/f6CyDRz2Y2zOVp5/IFmI4TtrDFxa36xBqMNyQo3NJUBhq be1GRaGTCAVII8zt2P79VEiHHswTKWC6kDG77YgmXhLAMsHsXzxrnjppYHqd3B6JydwuCRc7+k7 pen5gixqPab/Ey4A5jek2VEbY84glby91tYgzLE0Lj4IumSBI18oguwFnmqoubUlAzDW8bfGAIu nLh+15CboT05F7cIxq238/UEgnRzAx2kYne3F99siP9xWuxjFwHDj9wGMYFH4yfcwuuI2sDuMti 3yAyIQ8AOEDthI34WI7IxbRZrmjK6zn2NSEv0XaUT1B5FiKKL/r1UPw81UUKO/kw== X-Received: by 2002:a05:620a:a19c:10b0:914:c01e:6f92 with SMTP id af79cd13be357-9153d9709f3mr614876885a.18.1780179598221; Sat, 30 May 2026 15:19:58 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:57 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 08/13] liveupdate: defer session block allocation and PA setting Date: Sat, 30 May 2026 22:19:33 +0000 Message-ID: <20260530221938.115978-9-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, luo_session_setup_outgoing() allocates the session block and sets its physical address in the header immediately. With upcoming dynamic block-based session management, this makes the first block different from the rest. Move the allocation to where it is first needed. Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- kernel/liveupdate/luo_core.c | 4 +- kernel/liveupdate/luo_internal.h | 2 +- kernel/liveupdate/luo_session.c | 68 ++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index e261a03a1b47..fef7fc6765e3 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -161,9 +161,7 @@ static int __init luo_state_setup(void) strscpy(luo_ser->compatible, LUO_ABI_COMPATIBLE, sizeof(luo_ser->compatib= le)); luo_ser->liveupdate_num =3D luo_global.liveupdate_num + 1; =20 - err =3D luo_session_setup_outgoing(&luo_ser->sessions_pa); - if (err) - goto exit_free_luo_ser; + luo_session_setup_outgoing(&luo_ser->sessions_pa); =20 err =3D luo_flb_setup_outgoing(&luo_ser->flbs_pa); if (err) diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_inter= nal.h index fe22086bfbeb..ee18f9a11b91 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -79,7 +79,7 @@ extern struct rw_semaphore luo_register_rwlock; =20 int luo_session_create(const char *name, struct file **filep); int luo_session_retrieve(const char *name, struct file **filep); -int __init luo_session_setup_outgoing(u64 *sessions_pa); +void __init luo_session_setup_outgoing(u64 *sessions_pa); int __init luo_session_setup_incoming(u64 sessions_pa); int luo_session_serialize(void); int luo_session_deserialize(void); diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index b728fd9e3ed2..0548d48bb014 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -108,15 +108,16 @@ static DECLARE_RWSEM(luo_session_serialize_rwsem); =20 /** * struct luo_session_header - Header struct for managing LUO sessions. - * @count: The number of sessions currently tracked in the @list. - * @list: The head of the linked list of `struct luo_session` instan= ces. - * @rwsem: A read-write semaphore providing synchronized access to the - * session list and other fields in this structure. - * @header_ser: The header data of serialization array. - * @ser: The serialized session data (an array of - * `struct luo_session_ser`). - * @active: Set to true when first initialized. If previous kernel did= not - * send session data, active stays false for incoming. + * @count: The number of sessions currently tracked in the @list. + * @list: The head of the linked list of `struct luo_session` insta= nces. + * @rwsem: A read-write semaphore providing synchronized access to t= he + * session list and other fields in this structure. + * @header_ser: The header data of serialization array. + * @ser: The serialized session data (an array of + * `struct luo_session_ser`). + * @sessions_pa: Points to the location of sessions_pa within struct luo_s= er. + * @active: Set to true when first initialized. If previous kernel di= d not + * send session data, active stays false for incoming. */ struct luo_session_header { long count; @@ -124,6 +125,7 @@ struct luo_session_header { struct rw_semaphore rwsem; struct luo_session_header_ser *header_ser; struct luo_session_ser *ser; + u64 *sessions_pa; bool active; }; =20 @@ -171,10 +173,30 @@ static void luo_session_free(struct luo_session *sess= ion) kfree(session); } =20 +static int luo_session_grow_ser(struct luo_session_header *sh) +{ + struct luo_session_header_ser *header_ser; + + if (sh->count =3D=3D LUO_SESSION_MAX) + return -ENOMEM; + + if (sh->header_ser) + return 0; + + header_ser =3D kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT); + if (IS_ERR(header_ser)) + return PTR_ERR(header_ser); + + sh->header_ser =3D header_ser; + sh->ser =3D (void *)(header_ser + 1); + return 0; +} + static int luo_session_insert(struct luo_session_header *sh, struct luo_session *session) { struct luo_session *it; + int err; =20 guard(rwsem_write)(&sh->rwsem); =20 @@ -183,8 +205,9 @@ static int luo_session_insert(struct luo_session_header= *sh, * for new session. */ if (sh =3D=3D &luo_session_global.outgoing) { - if (sh->count =3D=3D LUO_SESSION_MAX) - return -ENOMEM; + err =3D luo_session_grow_ser(sh); + if (err) + return err; } =20 /* @@ -494,21 +517,10 @@ int luo_session_retrieve(const char *name, struct fil= e **filep) return err; } =20 -int __init luo_session_setup_outgoing(u64 *sessions_pa) +void __init luo_session_setup_outgoing(u64 *sessions_pa) { - struct luo_session_header_ser *header_ser; - - header_ser =3D kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT); - if (IS_ERR(header_ser)) - return PTR_ERR(header_ser); - - *sessions_pa =3D virt_to_phys(header_ser); - - luo_session_global.outgoing.header_ser =3D header_ser; - luo_session_global.outgoing.ser =3D (void *)(header_ser + 1); + luo_session_global.outgoing.sessions_pa =3D sessions_pa; luo_session_global.outgoing.active =3D true; - - return 0; } =20 int __init luo_session_setup_incoming(u64 sessions_pa) @@ -610,6 +622,8 @@ int luo_session_serialize(void) =20 down_write(&luo_session_serialize_rwsem); down_write(&sh->rwsem); + *sh->sessions_pa =3D 0; + list_for_each_entry(session, &sh->list, list) { err =3D luo_session_freeze_one(session, &sh->ser[i]); if (err) @@ -619,7 +633,11 @@ int luo_session_serialize(void) sizeof(sh->ser[i].name)); i++; } - sh->header_ser->count =3D sh->count; + + if (sh->header_ser && sh->count > 0) { + sh->header_ser->count =3D sh->count; + *sh->sessions_pa =3D virt_to_phys(sh->header_ser); + } up_write(&sh->rwsem); =20 return 0; --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (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 6EFE2378D86 for ; Sat, 30 May 2026 22:20:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179604; cv=none; b=diL4XMJOCANLMj78ooE1nzIFQugbP+XsNLlAVGzGgV0vxTc1ExmdloYgwnHM9+4kHEYBc+afgPIzwpxbGfMQp3L//3K6d0MNdcsfkKfG0R+pDHaIWimXS6k0/EEN/Q3BI2k4RMdxEr0AqgIoM1V6zrxGOkyPnt03RLHtx15e0Mg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179604; c=relaxed/simple; bh=+rG3BSh7m1s5MuWBwwKi1M63YKg7nrGZHONlg1KGaJM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f8Ph8yE3OoKUgTev2ys7FU1gOrsU4nkDVIKFfUBB7eK1pbfu/QCj6Vwa9sLhOoAGswE3CsVFUuh4Wcb/Ml49nWag6/TCwcyv/PFSyzxJgRDa47b4dys4rLisvuLVQh7wLuQCANJFBRUtaNJPj4TXMuN99jE5rtZijqxHEF/9flY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=f0UPZW7r; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="f0UPZW7r" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-91550c6ea8eso26960785a.0 for ; Sat, 30 May 2026 15:20:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179599; x=1780784399; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Imn772bBjRXOhvJWwenfZMGCHENcf6UnvP7wc5uTi4I=; b=f0UPZW7rp+OU1WFAq1T52M/55PLD0gaPgYCHfR46HS5Qa2G3+Mw2ciYXtSBrDlXg22 0ffNHlSEwGLJxt3W0NDmyyLsALdrVJ12IRMmkV5n23poWcrF5lSGr0SLKqLq18ZjzjhI vtJCvGcyn3Imw6pLH5jmeGHWSx9jKDAEsn4BqBKoz8FwnTfaK4iqmn7A0haqPkAVh/7V TE72FC9OCVRCopbEP8o5FbUHOABfF5Ggdj1kF7zhyvODfWXpEG9RLO+gaJON3V0h01eH 4wrK3SQ7z0H/+jKsvD8dZjgdeKkxyz1UB8fes5tfR4IWRbZfJwTwggVF4bCBOZbal1gP 98dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179599; x=1780784399; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Imn772bBjRXOhvJWwenfZMGCHENcf6UnvP7wc5uTi4I=; b=O9a6C/gSKPEzuGK4954FKnNdKpyY1q0AHTLKDFk3Kn0xFc4dvFbZGVR3LTbY0LCGU1 xwWXNORBAdMKYHhRZmMUlpiDo8qdimjCYyqhyOpXVq0K+D02XGC+s6cVd/SPqwaCWtmp 7PTB9vwTIVrco9r/ZKMsPTqp4BJl66bU0pjNmGK9Po0rOa52UT80UJoOerf2Bm1CwhQq 84lahco219aEXM+x9rOv1g46xGwadGLwZs4cSaA/Xl3ub/y5wKpN83VB4rYE0zXq/+EB xsaTan0GtYKqAmEnaZx7a0BE1uVJF2mWhKGpOiUpo/hmMW3jVRak0NZuozNtikzDaO4l rFOg== X-Forwarded-Encrypted: i=1; AFNElJ/J//fOGP3rpd1hXsKwHh4c3Wm7kyI5NUqMFyAHpcFg3lnjB54zoltDOCorDzD1WL+4J9j6C06CnXQGQ+U=@vger.kernel.org X-Gm-Message-State: AOJu0YycOv/fi+fWcTKiGMTlp5q3r/n6/iFY/XvDoUbI6WHlObbhVHCU CJbXQJkCddc0liENBPY8ycjDnTzjWsgHm/0ntsss3jdvJ7lIOOuHCjGDnDC2gWbuvag= X-Gm-Gg: Acq92OF9AlbbprgTly5SwYQukdNId0hIMPLMqxwB7EJa+AbXkRguCIS+o14JRsNgbm5 3zgLJY8U+uhRPc07AsFr5nIvPbpaqnzBXWCHrnMgNEMGRI48Q4nIX6A2YigVczpiym91s4aDOlw 1rWLgDoP20bjuCFs3yvYqgbL7nJU2xvQYifrZHrSJkCgfRbhh/i/lN7hCozkN4VLFXgmWT6dZSJ x/1of1NjlvToC1Vt0RpVMyJFNCBnfRDCsjmaOqylXpD//Von6zvpkAfddtx8vpAtBPEfMVon5S3 Mc06Thj9lRkzGCIdIXsDEZhNbMXS2dejsFt61KTho9KrExcJuO2vi4ThLWemwMXta0vcC+DFzxD XozSyzAOQCB6tu9xKaa8/19SH5edzjkhSxmqb6WgMO7AIbouW56x0OhIF8UNl/C82DEN9beQ/SZ HC0Vm8etuD9ZUFf2V6UhovZ5s5JkUu6pxqj0kTYWgVJuuKksJg7+MAYRvlwcrXTg== X-Received: by 2002:a05:620a:40c1:b0:914:ca5a:60aa with SMTP id af79cd13be357-9153d9cb8f7mr857976385a.6.1780179599475; Sat, 30 May 2026 15:19:59 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:19:59 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 09/13] liveupdate: Remove limit on the number of sessions Date: Sat, 30 May 2026 22:19:34 +0000 Message-ID: <20260530221938.115978-10-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, the number of LUO sessions is limited by a fixed number of pre-allocated pages for serialization (16 pages, allowing for ~819 sessions). This limitation is problematic if LUO is used to support things such as systemd file descriptor store, and would be used not just as VM memory but to save other states on the machine. Remove this limit by transitioning to a linked-block approach for session metadata serialization. Instead of a single contiguous block, session metadata is now stored in a chain of 16-page blocks. Each block starts with a header containing the physical address of the next block and the number of session entries in the current block. Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- include/linux/kho/abi/luo.h | 24 +------ kernel/liveupdate/luo_session.c | 117 +++++++++++++++----------------- 2 files changed, 58 insertions(+), 83 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 9a4fe491812b..79758d92ed5f 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -33,11 +33,6 @@ * It includes the compatibility string, the liveupdate-number, and po= inters * to sessions and FLBs. * - * - struct luo_session_header_ser: - * Header for the session array. Contains the total page count of the - * preserved memory block and the number of `struct luo_session_ser` - * entries that follow. - * * - struct luo_session_ser: * Metadata for a single session, including its name and a physical po= inter * to another preserved memory block containing an array of @@ -63,13 +58,15 @@ #define _LINUX_KHO_ABI_LUO_H =20 #include +#include #include =20 /* * The LUO state is registered under this KHO entry name. */ #define LUO_KHO_ENTRY_NAME "LUO" -#define LUO_ABI_COMPATIBLE "luo-v3" +#define LUO_COMPAT_BASE "luo-v3" +#define LUO_ABI_COMPATIBLE LUO_COMPAT_BASE "-" KHO_BLOCK_ABI_COMPATIBLE #define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8) =20 /** @@ -118,21 +115,6 @@ struct luo_file_set_ser { u64 count; } __packed; =20 -/** - * struct luo_session_header_ser - Header for the serialized session data = block. - * @count: The number of `struct luo_session_ser` entries that immediately - * follow this header in the memory block. - * - * This structure is located at the beginning of a contiguous block of - * physical memory preserved across the kexec. It provides the necessary - * metadata to interpret the array of session entries that follow. - * - * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. - */ -struct luo_session_header_ser { - u64 count; -} __packed; - /** * struct luo_session_ser - Represents the serialized metadata for a LUO s= ession. * @name: The unique name of the session, provided by the userspac= e at diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index 0548d48bb014..f1a6c32eeb2b 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -24,9 +24,10 @@ * ioctls on /dev/liveupdate. * * - Serialization: Session metadata is preserved using the KHO framework.= When - * a live update is triggered via kexec, an array of `struct luo_session= _ser` - * is populated and placed in a preserved memory region. The physical ad= dress - * of this array is stored in the centralized `struct luo_ser` structure. + * a live update is triggered via kexec, session metadata is serialized = into + * a chain of linked-blocks and placed in a preserved memory region. The + * physical address of the first block header is stored in the centraliz= ed + * `struct luo_ser` structure. * * Session Lifecycle: * @@ -89,6 +90,7 @@ #include #include #include +#include #include #include #include @@ -98,23 +100,14 @@ #include #include "luo_internal.h" =20 -/* 16 4K pages, give space for 744 sessions */ -#define LUO_SESSION_PGCNT 16ul -#define LUO_SESSION_MAX (((LUO_SESSION_PGCNT << PAGE_SHIFT) - \ - sizeof(struct luo_session_header_ser)) / \ - sizeof(struct luo_session_ser)) - static DECLARE_RWSEM(luo_session_serialize_rwsem); - /** * struct luo_session_header - Header struct for managing LUO sessions. * @count: The number of sessions currently tracked in the @list. * @list: The head of the linked list of `struct luo_session` insta= nces. * @rwsem: A read-write semaphore providing synchronized access to t= he * session list and other fields in this structure. - * @header_ser: The header data of serialization array. - * @ser: The serialized session data (an array of - * `struct luo_session_ser`). + * @block_set: The set of serialization blocks. * @sessions_pa: Points to the location of sessions_pa within struct luo_s= er. * @active: Set to true when first initialized. If previous kernel di= d not * send session data, active stays false for incoming. @@ -123,8 +116,7 @@ struct luo_session_header { long count; struct list_head list; struct rw_semaphore rwsem; - struct luo_session_header_ser *header_ser; - struct luo_session_ser *ser; + struct kho_block_set block_set; u64 *sessions_pa; bool active; }; @@ -143,10 +135,14 @@ static struct luo_session_global luo_session_global = =3D { .incoming =3D { .list =3D LIST_HEAD_INIT(luo_session_global.incoming.list), .rwsem =3D __RWSEM_INITIALIZER(luo_session_global.incoming.rwsem), + .block_set =3D KHO_BLOCK_SET_INIT(luo_session_global.incoming.block_set, + sizeof(struct luo_session_ser)), }, .outgoing =3D { .list =3D LIST_HEAD_INIT(luo_session_global.outgoing.list), .rwsem =3D __RWSEM_INITIALIZER(luo_session_global.outgoing.rwsem), + .block_set =3D KHO_BLOCK_SET_INIT(luo_session_global.outgoing.block_set, + sizeof(struct luo_session_ser)), }, }; =20 @@ -173,25 +169,6 @@ static void luo_session_free(struct luo_session *sessi= on) kfree(session); } =20 -static int luo_session_grow_ser(struct luo_session_header *sh) -{ - struct luo_session_header_ser *header_ser; - - if (sh->count =3D=3D LUO_SESSION_MAX) - return -ENOMEM; - - if (sh->header_ser) - return 0; - - header_ser =3D kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT); - if (IS_ERR(header_ser)) - return PTR_ERR(header_ser); - - sh->header_ser =3D header_ser; - sh->ser =3D (void *)(header_ser + 1); - return 0; -} - static int luo_session_insert(struct luo_session_header *sh, struct luo_session *session) { @@ -205,7 +182,7 @@ static int luo_session_insert(struct luo_session_header= *sh, * for new session. */ if (sh =3D=3D &luo_session_global.outgoing) { - err =3D luo_session_grow_ser(sh); + err =3D kho_block_grow(&sh->block_set, sh->count); if (err) return err; } @@ -232,6 +209,8 @@ static void luo_session_remove(struct luo_session_heade= r *sh, guard(rwsem_write)(&sh->rwsem); list_del(&session->list); sh->count--; + if (sh =3D=3D &luo_session_global.outgoing) + kho_block_shrink(&sh->block_set, sh->count); } =20 static int luo_session_finish_one(struct luo_session *session) @@ -525,15 +504,17 @@ void __init luo_session_setup_outgoing(u64 *sessions_= pa) =20 int __init luo_session_setup_incoming(u64 sessions_pa) { - struct luo_session_header_ser *header_ser; + struct luo_session_header *sh =3D &luo_session_global.incoming; + int err; =20 - if (sessions_pa) { - header_ser =3D phys_to_virt(sessions_pa); - luo_session_global.incoming.header_ser =3D header_ser; - luo_session_global.incoming.ser =3D (void *)(header_ser + 1); - luo_session_global.incoming.active =3D true; - } + if (!sessions_pa) + return 0; + + err =3D kho_block_restore(&sh->block_set, sessions_pa); + if (err) + return err; =20 + sh->active =3D true; return 0; } =20 @@ -575,6 +556,8 @@ int luo_session_deserialize(void) { struct luo_session_header *sh =3D &luo_session_global.incoming; static bool is_deserialized; + struct luo_session_ser *ser; + struct kho_block_it it; static int err; =20 /* If has been deserialized, always return the same error code */ @@ -600,53 +583,63 @@ int luo_session_deserialize(void) * userspace to detect the failure and trigger a reboot, which will * reliably reset devices and reclaim memory. */ - for (int i =3D 0; i < sh->header_ser->count; i++) { - err =3D luo_session_deserialize_one(sh, &sh->ser[i]); + kho_block_it_init(&it, &sh->block_set); + while ((ser =3D kho_block_it_read(&it))) { + err =3D luo_session_deserialize_one(sh, ser); if (err) - return err; + goto err_destroy_blocks; } =20 - kho_restore_free(sh->header_ser); - sh->header_ser =3D NULL; - sh->ser =3D NULL; +err_destroy_blocks: + kho_block_destroy(&sh->block_set); =20 - return 0; + return err; } =20 int luo_session_serialize(void) { struct luo_session_header *sh =3D &luo_session_global.outgoing; struct luo_session *session; - int i =3D 0; + struct kho_block_it it; int err; =20 down_write(&luo_session_serialize_rwsem); down_write(&sh->rwsem); *sh->sessions_pa =3D 0; =20 + kho_block_it_init(&it, &sh->block_set); + list_for_each_entry(session, &sh->list, list) { - err =3D luo_session_freeze_one(session, &sh->ser[i]); - if (err) + struct luo_session_ser *ser =3D kho_block_it_next(&it); + + if (!ser) { + err =3D -ENOSPC; goto err_undo; + } =20 - strscpy(sh->ser[i].name, session->name, - sizeof(sh->ser[i].name)); - i++; - } + err =3D luo_session_freeze_one(session, ser); + if (err) { + kho_block_it_prev(&it); + goto err_undo; + } =20 - if (sh->header_ser && sh->count > 0) { - sh->header_ser->count =3D sh->count; - *sh->sessions_pa =3D virt_to_phys(sh->header_ser); + strscpy(ser->name, session->name, sizeof(ser->name)); } + + kho_block_it_finalize(&it); + + if (sh->sessions_pa && sh->count > 0) + *sh->sessions_pa =3D sh->block_set.head_pa; up_write(&sh->rwsem); =20 return 0; =20 err_undo: list_for_each_entry_continue_reverse(session, &sh->list, list) { - i--; - luo_session_unfreeze_one(session, &sh->ser[i]); - memset(sh->ser[i].name, 0, sizeof(sh->ser[i].name)); + struct luo_session_ser *ser =3D kho_block_it_prev(&it); + + luo_session_unfreeze_one(session, ser); + memset(ser->name, 0, sizeof(ser->name)); } up_write(&sh->rwsem); up_write(&luo_session_serialize_rwsem); --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (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 AA66136A017 for ; Sat, 30 May 2026 22:20:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179606; cv=none; b=hrrwDxhsKj7P75MTAUTjdtGdDTtYdCHvOQsKQwlrqJjW/pHUVqYWQhHk/xOOXu/5JUF0SDzDJrdJeNG0mQZ+Aa8nrmxw6uDSWH5EnhYXRYeRLIfPbssNJLwpZtOF29uNdXUa8dssTHo97MdHh4cw6GwVzGvSiVQm1aw1gew3vAY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179606; c=relaxed/simple; bh=3F0n/sPzPA8UGrBcq7PA9PeKjeLryJWFl4qVZxT6ZAc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aPitumkwtlc5bJr6ZOmVT48ONG66jCdtBmgOsv7FpobjGHmqDjVdQhgH5Xk+oJ1JxAQgqRdQSl/plIPJvJY3I8J+RHeLeSU5Jmfdhi2ACEs+Pk5BoZP/RXcLfhtwDuGPoStFRuVbF8A6rtrlqdEBR1qAFdW11mYyVoCDOqoj+2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=LY5HHVmS; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="LY5HHVmS" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-914db83362aso716868285a.1 for ; Sat, 30 May 2026 15:20:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179601; x=1780784401; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=tnOZ578sANpIwoJ8k/GY/+cuz8LX/+y1E1AZj+iRbjA=; b=LY5HHVmSmiXIA+3NiqCFPU3IHY8JsXC4bwDpL3APARqZTw1cNKYcfo4o4jtBLIAQAr POA+PrW74lLCe22iOuhi92QhawLoxmFrurDCG//EpLb/4y+1P71/HKVgUGf0U8yUoUj4 FEB+Py46ol6w3DiKy5irnmdKUN44o69jBSg5mgOgIHIvSbXHwUlebrWWL7pFnhaAj8Tr PuMI2QMbmOyEDZ8SHaiB/BehW+yRggJu1KPqIEFB3T2qbJyCLBVTaK+gnJsvLRiLMEdz TzXfem/NCSP2iC1qSwjqfDhHZSkNy6FKbfmQVcFUm5eA+NOK6Ks8d8B1PBYXOdHkTGD4 0kDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179601; x=1780784401; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=tnOZ578sANpIwoJ8k/GY/+cuz8LX/+y1E1AZj+iRbjA=; b=qda+prZm4BTSac5j0LLU+2WgvqOVex8+FWzLnSZ6k6ZmIH73m3v+nM0eDcO5PKPg2n 30rRrQ4pDcmq0GrdwCci7DJ/LL7GjzU8Dszymskup0jppSue/w4wYFC7b2ti5wQZcaTG ckXlOlpQr4cuhPnScYkIwrG8YH0tUjzEFakqbHxM70ZurSUGTKMlBFa4vrQ7DHcVCE4s 1o6N+OKSIt14RAnG32IrCwa0/E77QoYoAMasX5s+0OBrfBwpZkrzi2sI4v5f/oIJThrX tIHsYMAvO8JEKmXumEZRKdOiSHvUFxmHniRN5fPS8Cx8CbxUqbsedcnlW5rfrSwk7Jlz sJtA== X-Forwarded-Encrypted: i=1; AFNElJ+lwoMRRncm5rfUDiYXSPKQZpRHeMHH25Z+SZBveHUFNJZUHiJ1yD0YubTTLnEcftFOIecY3FWRIIOPAGU=@vger.kernel.org X-Gm-Message-State: AOJu0YwnAYzTKxlmXuOeCVZMJgCFWp5FrFLNsno6ZNClPkhC2V/VX5cm LDWBuR9NPqjbRL5mmoNfY8Q0cv+8Jdq8xJLWNdQsXH2p4cKNqJDfsGLjbpeG34gwRw0= X-Gm-Gg: Acq92OGeqlqv6uztpbQ4Bt8BWXSTDTTJhv38aewzIeEMZaraDPaBfvK2aLv6L5d8yoM hbm3Xspcb/Zsmu9FnQioj539vjwwbEFPs1V7ewBmBrRU2lYD8fF6HyPOAkbtBq5DvZj2Tyt7G0J GHmlfQyaz74dvsnO8EsiIe4tDhX5mG8675Ife18xBCVC7gCiK2crcgo5TRdva2bdcFhim7RGc+/ ZaqhBdfMCJUb34KKs5Kvf6VwVrksaPI9yXHTm35MmNy03G0JqXtOvjwP+aReTgyxypOsZRXsUTM z5mxT33R3Ev6CPLhMLd35854Ni+15P/fwLHte1/6HrN4bBj5J0dpMI4EeLS7CYwQhvhICCEwMRR 2ZePJFCD2Yvy/K+rrfGvSmEz3qr5p0iqdOsp7zYVLmgMJTODvwDLbZMtcCRqBnhy/vzQsp3Q7d2 pWE94FoIiQH+WRFpx+sN06mnwHF6gullrZcQrGFyKwJ2WF3yvgWb7IQRLGWtvmeQ== X-Received: by 2002:a05:620a:3181:b0:915:351b:3ad5 with SMTP id af79cd13be357-9153e16e848mr609702785a.29.1780179600683; Sat, 30 May 2026 15:20:00 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.19.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:20:00 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 10/13] liveupdate: Remove limit on the number of files per session Date: Sat, 30 May 2026 22:19:35 +0000 Message-ID: <20260530221938.115978-11-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To remove the fixed limit on the number of preserved files per session, transition the file metadata serialization from a single contiguous memory block to a chain of linked blocks. Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin --- include/linux/kho/abi/luo.h | 13 +-- kernel/liveupdate/luo_file.c | 144 +++++++++++++++---------------- kernel/liveupdate/luo_internal.h | 6 +- 3 files changed, 80 insertions(+), 83 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 79758d92ed5f..16df550ef143 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -35,8 +35,8 @@ * * - struct luo_session_ser: * Metadata for a single session, including its name and a physical po= inter - * to another preserved memory block containing an array of - * `struct luo_file_ser` for all files in that session. + * to the first `struct kho_block_header_ser` for all files in that se= ssion. + * Multiple blocks are linked via the `next` field in the header. * * - struct luo_file_ser: * Metadata for a single preserved file. Contains the `compatible` str= ing to @@ -65,7 +65,7 @@ * The LUO state is registered under this KHO entry name. */ #define LUO_KHO_ENTRY_NAME "LUO" -#define LUO_COMPAT_BASE "luo-v3" +#define LUO_COMPAT_BASE "luo-v4" #define LUO_ABI_COMPATIBLE LUO_COMPAT_BASE "-" KHO_BLOCK_ABI_COMPATIBLE #define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8) =20 @@ -103,9 +103,10 @@ struct luo_file_ser { =20 /** * struct luo_file_set_ser - Represents the serialized metadata for file s= et - * @files: The physical address of a contiguous memory block that holds - * the serialized state of files (array of luo_file_ser) in this= file - * set. + * @files: The physical address of the first `struct kho_block_header_se= r`. + * This structure is the header for a block of memory containing + * an array of `struct luo_file_ser` entries. Multiple blocks are + * linked via the `next` field in the header. * @count: The total number of files that were part of this session duri= ng * serialization. Used for iteration and validation during * restoration. diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index 9eec07a9e9fc..a445b1950ca7 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -118,11 +118,6 @@ static LIST_HEAD(luo_file_handler_list); /* Keep track of files being preserved by LUO */ static DEFINE_XARRAY(luo_preserved_files); =20 -/* 2 4K pages, give space for 128 files per file_set */ -#define LUO_FILE_PGCNT 2ul -#define LUO_FILE_MAX \ - ((LUO_FILE_PGCNT << PAGE_SHIFT) / sizeof(struct luo_file_ser)) - /** * struct luo_file - Represents a single preserved file instance. * @fh: Pointer to the &struct liveupdate_file_handler that man= ages @@ -174,39 +169,6 @@ struct luo_file { u64 token; }; =20 -static int luo_alloc_files_mem(struct luo_file_set *file_set) -{ - size_t size; - void *mem; - - if (file_set->files) - return 0; - - WARN_ON_ONCE(file_set->count); - - size =3D LUO_FILE_PGCNT << PAGE_SHIFT; - mem =3D kho_alloc_preserve(size); - if (IS_ERR(mem)) - return PTR_ERR(mem); - - file_set->files =3D mem; - - return 0; -} - -static void luo_free_files_mem(struct luo_file_set *file_set) -{ - /* If file_set has files, no need to free preservation memory */ - if (file_set->count) - return; - - if (!file_set->files) - return; - - kho_unpreserve_free(file_set->files); - file_set->files =3D NULL; -} - static unsigned long luo_get_id(struct liveupdate_file_handler *fh, struct file *file) { @@ -276,16 +238,15 @@ int luo_preserve_file(struct luo_file_set *file_set, = u64 token, int fd) if (luo_token_is_used(file_set, token)) return -EEXIST; =20 - if (file_set->count =3D=3D LUO_FILE_MAX) - return -ENOSPC; + err =3D kho_block_grow(&file_set->block_set, file_set->count); + if (err) + return err; =20 file =3D fget(fd); - if (!file) - return -EBADF; - - err =3D luo_alloc_files_mem(file_set); - if (err) - goto err_fput; + if (!file) { + err =3D -EBADF; + goto err_shrink; + } =20 err =3D -ENOENT; down_read(&luo_register_rwlock); @@ -300,7 +261,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u6= 4 token, int fd) =20 /* err is still -ENOENT if no handler was found */ if (err) - goto err_free_files_mem; + goto err_fput; =20 err =3D xa_insert(&luo_preserved_files, luo_get_id(fh, file), file, GFP_KERNEL); @@ -343,10 +304,10 @@ int luo_preserve_file(struct luo_file_set *file_set, = u64 token, int fd) xa_erase(&luo_preserved_files, luo_get_id(fh, file)); err_module_put: module_put(fh->ops->owner); -err_free_files_mem: - luo_free_files_mem(file_set); err_fput: fput(file); +err_shrink: + kho_block_shrink(&file_set->block_set, file_set->count); =20 return err; } @@ -392,13 +353,14 @@ void luo_file_unpreserve_files(struct luo_file_set *f= ile_set) =20 list_del(&luo_file->list); file_set->count--; + kho_block_shrink(&file_set->block_set, file_set->count); =20 fput(luo_file->file); mutex_destroy(&luo_file->mutex); kfree(luo_file); } =20 - luo_free_files_mem(file_set); + kho_block_destroy(&file_set->block_set); } =20 static int luo_file_freeze_one(struct luo_file_set *file_set, @@ -454,7 +416,7 @@ static void __luo_file_unfreeze(struct luo_file_set *fi= le_set, luo_file_unfreeze_one(file_set, luo_file); } =20 - memset(file_set->files, 0, LUO_FILE_PGCNT << PAGE_SHIFT); + kho_block_set_clear(&file_set->block_set); } =20 /** @@ -493,19 +455,23 @@ static void __luo_file_unfreeze(struct luo_file_set *= file_set, int luo_file_freeze(struct luo_file_set *file_set, struct luo_file_set_ser *file_set_ser) { - struct luo_file_ser *file_ser =3D file_set->files; struct luo_file *luo_file; + struct kho_block_it it; int err; - int i; =20 if (!file_set->count) return 0; =20 - if (WARN_ON(!file_ser)) - return -EINVAL; + kho_block_it_init(&it, &file_set->block_set); =20 - i =3D 0; list_for_each_entry(luo_file, &file_set->files_list, list) { + struct luo_file_ser *file_ser =3D kho_block_it_next(&it); + + if (!file_ser) { + err =3D -ENOSPC; + goto err_unfreeze; + } + err =3D luo_file_freeze_one(file_set, luo_file); if (err < 0) { pr_warn("Freeze failed for token[%#0llx] handler[%s] err[%pe]\n", @@ -514,16 +480,21 @@ int luo_file_freeze(struct luo_file_set *file_set, goto err_unfreeze; } =20 - strscpy(file_ser[i].compatible, luo_file->fh->compatible, - sizeof(file_ser[i].compatible)); - file_ser[i].data =3D luo_file->serialized_data; - file_ser[i].token =3D luo_file->token; - i++; + strscpy(file_ser->compatible, luo_file->fh->compatible, + sizeof(file_ser->compatible)); + file_ser->data =3D luo_file->serialized_data; + file_ser->token =3D luo_file->token; } + kho_block_it_finalize(&it); =20 file_set_ser->count =3D file_set->count; - if (file_set->files) - file_set_ser->files =3D virt_to_phys(file_set->files); + if (!list_empty(&file_set->block_set.blocks)) { + struct kho_block *block; + + block =3D list_first_entry(&file_set->block_set.blocks, + struct kho_block, list); + file_set_ser->files =3D virt_to_phys(block->ser); + } =20 return 0; =20 @@ -741,14 +712,12 @@ int luo_file_finish(struct luo_file_set *file_set) module_put(luo_file->fh->ops->owner); list_del(&luo_file->list); file_set->count--; + kho_block_shrink(&file_set->block_set, file_set->count); mutex_destroy(&luo_file->mutex); kfree(luo_file); } =20 - if (file_set->files) { - kho_restore_free(file_set->files); - file_set->files =3D NULL; - } + kho_block_destroy(&file_set->block_set); =20 return 0; } @@ -822,16 +791,18 @@ int luo_file_deserialize(struct luo_file_set *file_se= t, struct luo_file_set_ser *file_set_ser) { struct luo_file_ser *file_ser; + struct kho_block_it it; int err; - u64 i; =20 if (!file_set_ser->files) { WARN_ON(file_set_ser->count); return 0; } =20 - file_set->count =3D file_set_ser->count; - file_set->files =3D phys_to_virt(file_set_ser->files); + file_set->count =3D 0; + err =3D kho_block_restore(&file_set->block_set, file_set_ser->files); + if (err) + return err; =20 /* * Note on error handling: @@ -848,25 +819,50 @@ int luo_file_deserialize(struct luo_file_set *file_se= t, * userspace to detect the failure and trigger a reboot, which will * reliably reset devices and reclaim memory. */ - file_ser =3D file_set->files; - for (i =3D 0; i < file_set->count; i++) { - err =3D luo_file_deserialize_one(file_set, &file_ser[i]); + kho_block_it_init(&it, &file_set->block_set); + while ((file_ser =3D kho_block_it_read(&it))) { + err =3D luo_file_deserialize_one(file_set, file_ser); if (err) - return err; + goto err_destroy_blocks; + file_set->count++; + } + + if (file_set->count !=3D file_set_ser->count) { + pr_warn("File count mismatch: expected %llu, found %llu\n", + file_set_ser->count, file_set->count); + err =3D -EINVAL; + goto err_destroy_blocks; } =20 return 0; + +err_destroy_blocks: + while (!list_empty(&file_set->files_list)) { + struct luo_file *luo_file; + + luo_file =3D list_first_entry(&file_set->files_list, + struct luo_file, list); + list_del(&luo_file->list); + module_put(luo_file->fh->ops->owner); + mutex_destroy(&luo_file->mutex); + kfree(luo_file); + } + file_set->count =3D 0; + kho_block_destroy(&file_set->block_set); + return err; } =20 void luo_file_set_init(struct luo_file_set *file_set) { INIT_LIST_HEAD(&file_set->files_list); + kho_block_set_init(&file_set->block_set, sizeof(struct luo_file_ser)); } =20 void luo_file_set_destroy(struct luo_file_set *file_set) { WARN_ON(file_set->count); WARN_ON(!list_empty(&file_set->files_list)); + WARN_ON(!list_empty(&file_set->block_set.blocks)); } =20 /** diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_inter= nal.h index ee18f9a11b91..64879ffe7378 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -10,6 +10,7 @@ =20 #include #include +#include =20 struct luo_ucmd { void __user *ubuffer; @@ -44,14 +45,13 @@ static inline int luo_ucmd_respond(struct luo_ucmd *ucm= d, * struct luo_file_set - A set of files that belong to the same sessions. * @files_list: An ordered list of files associated with this session, it = is * ordered by preservation time. - * @files: The physically contiguous memory block that holds the seri= alized - * state of files. + * @block_set: The set of serialization blocks. * @count: A counter tracking the number of files currently stored in= the * @files_list for this session. */ struct luo_file_set { struct list_head files_list; - struct luo_file_ser *files; + struct kho_block_set block_set; u64 count; }; =20 --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (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 C3399341077 for ; Sat, 30 May 2026 22:20:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179605; cv=none; b=srJujIHhJi4aNN1xI9dfyVdCpVThuFOATxCzm+gpjv6LRbTI1SfhEyNkDUe9VBqNFWFSJaSB1FPsae1KB4zD/OIESV5x9e1FdslJ7f03LrnBthxGHtqzMgmHxAJcgu9ni4YaAtppoujmYdyVgqTlsmFKs8niEathhNwids58YOU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179605; c=relaxed/simple; bh=l5sCPInN24558zDa0DI5TQ1DcCXBUgAOZ3PiWzJQJoI=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ULV6bREGqhEzwVf7tW732dc1M3Iz10ABk6ROJ8Nw+QawpcF63NTR+wlGruUqVAf3Bpcd//8BcjZexr5/URsROQHcx5cMCuPd9PAlPO4rgzKjMhP+F6ln42EsN8C2jSxgC2rFMTHYbESeGgtPKkh98cM2HbG4Xj8BgnNZ0pFp6wY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=UbRANhl7; arc=none smtp.client-ip=209.85.222.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="UbRANhl7" Received: by mail-qk1-f179.google.com with SMTP id af79cd13be357-91550c6ea8eso26962485a.0 for ; Sat, 30 May 2026 15:20:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179602; x=1780784402; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=l/PRPWvWF9f7qW0XjjBpwGc/NadY8LWCtXHDn2RYoSI=; b=UbRANhl7Z1zD09kwlBAc/uuNUHzbsyQ2LsqHRGtyaAG2B41vtl5s1pD7T/CeVP2XZz 3KTGvbXNifl2Wa0wy0n/GPr3BA7b4mlKk5Mz9IzlZi6yNLw+mqznhH4sI8Nnq3afhQEc 5qhwTbTkMWbq2iW4iVaVtEeCqF9/2IAVLxSkkfRxGgUhEKxWxpEepkf63QBst0N+gh2Y jFcrezpQq0Dj0/8patMbr3nKoIIhvLQj17pmx5dAIlugLKChItZIzL+2ar0AN99eB8U2 KB+UXO2TKodW2pG8EuzwixWYqNqepQ8ianS1o4biX3XNYcG0+fhFSFJmBEdev3/7jju9 WBmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179602; x=1780784402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=l/PRPWvWF9f7qW0XjjBpwGc/NadY8LWCtXHDn2RYoSI=; b=obxrdtvGnJri8dYBCB6vuzJu4zM/rSeIGFl8tWqYfbujm8MVrOaXb9ERVcEzhliohe DfEx+m0YK9ZyK560e7AOLe0+SQlumWe/qgvBtj9ueu5hShrwhtN9o/psBMPihwAhUe2a r6hwVM/VQmHIXc51kPzXpxpv2mQyWVJsOdP9olGZEcJRKUYsGizyIsvyMm1ad+2u8MUS eZJ5fl+adhzXCXmLlXD4jP9TJ+aawkJfN1ozTd0wXvxiAhDJ9O3QTfRCdDN9qGvn0Z3o 1EJmxeGAmplrGWMZQVdqDXDEvltngPOTGnwiSe13uwro1pqBGxFv7b77t4BRXaZkWQ4r i5+A== X-Forwarded-Encrypted: i=1; AFNElJ9MDpmjnDJw/2ElpgLj/w6CcsRsXOCWQZN+w4E4WA2pBlCl14A06td8k+7ycRN0CkMFLRtLYEjEtYLatfA=@vger.kernel.org X-Gm-Message-State: AOJu0YxBnWd7zWe+YCrNrfUvUkNcvmNgxQPv8Zkbg72WoJtxGS1UFjyS n6puWkqHQJ1ud/tq1Iciq08nGzqGZNpOv5n/rFllQzP/4oF/MnZvKrhZqvm29XmjZl0= X-Gm-Gg: Acq92OGQh8lV4LPOHrcI4UeOVz1el4lUmBtE1UxErdo/RYnvtm20H48xbDn/zlkaVLa FpYylPa2L4w/4Whh850rk0neqNTwk6bilYhsEhmDsKYtW7POmXmpLrkQk1QHZcOIPiLttUvxZbn Cv84+sj5r3w+vDZUu1QZxoZ2H2MbSLYKOFI6/RcechB+WkkexES29jqg5CE7DyP/dJc5EzMXd1z nxwuxW4+Bqj5p/9e9pmL/WlgUtfrAUj/xAVy02ng3DSHMXc7ozydr80yEcdf2Ic+la9TndLjiB9 iBpnwVQ3cCmHPhTWpd82mNtvOBW+4SieOWx8XmNWnb9gS3QRJ7iB7IftFUzBl/DXPAUtZr+bEsm gdhGXSipfxA6h+7gDeu50RgG6ZixE8IWyWw9IHQAPgHVEBloM2ZIJS47pd26BNvwCIiBSZ0p656 WT9Hu41SljSMp4Q7NQtsJeZ4oBwJEVk94017Dcj1npV/Pjl56+jJKBx9XpFVr1WnfZ80cMfY2h X-Received: by 2002:a05:620a:648d:b0:914:db82:f791 with SMTP id af79cd13be357-9153dc29a52mr727746685a.49.1780179601868; Sat, 30 May 2026 15:20:01 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.20.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:20:01 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 11/13] selftests/liveupdate: Test session and file limit removal Date: Sat, 30 May 2026 22:19:36 +0000 Message-ID: <20260530221938.115978-12-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With the removal of static limits on the number of sessions and files per session, the orchestrator now uses dynamic allocation. Add new test cases to verify that the system can handle a large number of sessions and files. These tests ensure that the dynamic block allocation and reuse logic for session metadata and outgoing files work correctly beyond the previous static limits. Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- .../testing/selftests/liveupdate/liveupdate.c | 75 +++++++++++++++++++ .../selftests/liveupdate/luo_test_utils.c | 24 ++++++ .../selftests/liveupdate/luo_test_utils.h | 2 + 3 files changed, 101 insertions(+) diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testin= g/selftests/liveupdate/liveupdate.c index c7d94b9181e1..502fb3567e38 100644 --- a/tools/testing/selftests/liveupdate/liveupdate.c +++ b/tools/testing/selftests/liveupdate/liveupdate.c @@ -26,6 +26,7 @@ =20 #include =20 +#include "luo_test_utils.h" #include "../kselftest.h" #include "../kselftest_harness.h" =20 @@ -499,4 +500,78 @@ TEST_F(liveupdate_device, get_session_name_max_length) ASSERT_EQ(close(session_fd), 0); } =20 +/* + * Test Case: Manage Many Sessions + * + * Verifies that a large number of sessions can be created and then + * destroyed during normal system operation. This specifically tests the + * dynamic block allocation and reuse logic for session metadata management + * without preserving any files. + */ +TEST_F(liveupdate_device, preserve_many_sessions) +{ +#define MANY_SESSIONS 2000 + int session_fds[MANY_SESSIONS]; + int ret, i; + + self->fd1 =3D open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno =3D=3D ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + ret =3D luo_ensure_nofile_limit(MANY_SESSIONS); + if (ret =3D=3D -EPERM) + SKIP(return, "Insufficient privileges to set RLIMIT_NOFILE"); + ASSERT_EQ(ret, 0); + + for (i =3D 0; i < MANY_SESSIONS; i++) { + char name[64]; + + snprintf(name, sizeof(name), "many-session-%d", i); + session_fds[i] =3D create_session(self->fd1, name); + ASSERT_GE(session_fds[i], 0); + } + + for (i =3D 0; i < MANY_SESSIONS; i++) + ASSERT_EQ(close(session_fds[i]), 0); +} + +/* + * Test Case: Preserve Many Files + * + * Verifies that a large number of files can be preserved in a single sess= ion + * and then destroyed during normal system operation. This tests the dynam= ic + * block allocation and management for outgoing files. + */ +TEST_F(liveupdate_device, preserve_many_files) +{ +#define MANY_FILES 500 + int mem_fds[MANY_FILES]; + int session_fd, ret, i; + + self->fd1 =3D open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno =3D=3D ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + session_fd =3D create_session(self->fd1, "many-files-test"); + ASSERT_GE(session_fd, 0); + + ret =3D luo_ensure_nofile_limit(MANY_FILES + 10); + if (ret =3D=3D -EPERM) + SKIP(return, "Insufficient privileges to set RLIMIT_NOFILE"); + ASSERT_EQ(ret, 0); + + for (i =3D 0; i < MANY_FILES; i++) { + mem_fds[i] =3D memfd_create("test-memfd", 0); + ASSERT_GE(mem_fds[i], 0); + ASSERT_EQ(preserve_fd(session_fd, mem_fds[i], i), 0); + } + + for (i =3D 0; i < MANY_FILES; i++) + ASSERT_EQ(close(mem_fds[i]), 0); + + ASSERT_EQ(close(session_fd), 0); +} + TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/liveupdate/luo_test_utils.c b/tools/te= sting/selftests/liveupdate/luo_test_utils.c index 3c8721c505df..333a3530051b 100644 --- a/tools/testing/selftests/liveupdate/luo_test_utils.c +++ b/tools/testing/selftests/liveupdate/luo_test_utils.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,29 @@ int luo_open_device(void) return open(LUO_DEVICE, O_RDWR); } =20 +int luo_ensure_nofile_limit(long min_limit) +{ + struct rlimit hl; + + /* Allow to extra files to be used by test itself */ + min_limit +=3D 32; + + if (getrlimit(RLIMIT_NOFILE, &hl) < 0) + return -errno; + + if (hl.rlim_cur >=3D min_limit) + return 0; + + hl.rlim_cur =3D min_limit; + if (hl.rlim_cur > hl.rlim_max) + hl.rlim_max =3D hl.rlim_cur; + + if (setrlimit(RLIMIT_NOFILE, &hl) < 0) + return -errno; + + return 0; +} + int luo_create_session(int luo_fd, const char *name) { struct liveupdate_ioctl_create_session arg =3D { .size =3D sizeof(arg) }; diff --git a/tools/testing/selftests/liveupdate/luo_test_utils.h b/tools/te= sting/selftests/liveupdate/luo_test_utils.h index 90099bf49577..6a0d85386613 100644 --- a/tools/testing/selftests/liveupdate/luo_test_utils.h +++ b/tools/testing/selftests/liveupdate/luo_test_utils.h @@ -26,6 +26,8 @@ int luo_create_session(int luo_fd, const char *name); int luo_retrieve_session(int luo_fd, const char *name); int luo_session_finish(int session_fd); =20 +int luo_ensure_nofile_limit(long min_limit); + int create_and_preserve_memfd(int session_fd, int token, const char *data); int restore_and_verify_memfd(int session_fd, int token, const char *expect= ed_data); =20 --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) (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 D808E3783A2 for ; Sat, 30 May 2026 22:20:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179606; cv=none; b=cyA7mWus3/iNpBt2Z6cbFyXLI4o6i1WFAINnHMJx9xV4YGRp71ONwGmnZUTX3tpadz1YZ+mXqSELzkIRkcSAq2PfvZD9u7uCtV3LhiR1OWjN1Uf0OEqa8eYzBuyGjS9yKG0HAxSSsW4hx+9v1PPSGZgh6L+pr6Ep6B2LA4rOuy4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179606; c=relaxed/simple; bh=PwW6M86VtpCYbVanCRu9RC9XepQoEWHm1vY/6gS4fT8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oHEFg3AaatLWfqR0b6QuBgulaOTP7QPaUMVrB5ccphvLyhheljFzRTvHg7JN3mT7oRMbNZ0W9wrXYaPVvpYNunmukN296zkxmRvarOZ8lDMPMFxKI86A3+T1uk2BEK2TqOZOpg+2tBJ6PgiqDakKxZHAqBHcKgNrkXHyA/LcZdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=Lp5mv4Oj; arc=none smtp.client-ip=209.85.222.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="Lp5mv4Oj" Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-91541fa94aaso99600385a.2 for ; Sat, 30 May 2026 15:20:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179604; x=1780784404; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=zMNVhv3SnOTuZ3xqpMfMs2g7riJHPagItEAHtnUEWTI=; b=Lp5mv4Oj6Qz1Qet2yJKFpTE3zeQyNLOnctYYkLT2kYgsLrEaqal6v7ZUhbnZ0UP6qN Zd14FUOqJCOrSa24A/eJMFrP9ZGrRl8TBgv8xy3h8/FJJzP9UE1TsZvk+VwiAy5AxwWD vteIt4oNnA81O36sARggQ6qwmExvhyhI6rDmz/WdYnmgySNjS4zUCWDR/9VT7p8TS2gV V3Ds2j1QlTh+do06fTuLRG8PDU6hV48U2qHxi9HmNLgkm30/J2rNHPUbWCKlZyZAhGvt 8LqsqcOcp8E589KSyEwaJ0wL6U8i0Hb+IMwE2m7A6LqUGYcCOKdztW5+x4gqoIDE/JWa KKRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179604; x=1780784404; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=zMNVhv3SnOTuZ3xqpMfMs2g7riJHPagItEAHtnUEWTI=; b=H654zVfJReN0jml3vab6UCGai0+WjQuihaWglDzpWOCzNv17qGUVO9JgHkBfUH2jIk ivZPZIDLbl+qTHYfWifOyK/Y9DWimQAD5SVLbxkjG8kKFqAHl0fsfbbORQ5tETu8tX6E xQ74cjfjwiQfKPoUnAbj7UhFwkXPT4BJA/L2tmTbHKvOTTZwyTlAF5nwtKFSSWTgmpBK OuXxifIHU7u4Y3bnbbbkwdBbZ+0ztceWDOrnklsSaLcuERAy91D476e7Q/O+0DrvB3Ms MRr7C0esG0Seqs09SBlTNmdyL4P9lCuSMorH+fFINtLEt+aKjA8P1qd1OMrTYG9zUZmh lhbw== X-Forwarded-Encrypted: i=1; AFNElJ8TlaUmJKj4QAyqP6PwJTMf7RGLYPWTLFtIMX+cilx1UZ9+kuKfSjq4iTR8TPEqjFK511e9/gixPot0yFQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxaqI+odcUj/Bt08Ifl2UwIx47+nnN+bU68KtZL5LX+XcUWutPu /RbWzGqT/s0MqCfJM4DB8BngGxdqK9czib75vBgz3WdjHKZBU/rjB6ybRFY64/Au0+k= X-Gm-Gg: Acq92OFkbJQ77ua2yJS+shxzAss79gm0KKcumKzn694aycjkDE7Whbcns6v2mFShMqf SbqjPmDi/8XfEgh292IBZQMuc0HXp9g76bwVn4WCRJyEAS1munpGkVYtTbxy4EHIDUZ9rP3gok+ 8teZDBVrpM7yimQn0kWHkD9WomNu0gObNPPqZXRxXH+lZDArcoQNAckwn6qHHNsmPFp/DQaXLAM 2sBlvyqMECfChKSAJeyrk0AP1tnnw7AnnP4t50TJEzwBI+65WXHwX4RnBMwfFwax67frfGSs9DM usNg68Ma6Dkvl1Xgd27RvkjSCKFna7xjvqODOzIqQpV3rzv448M5b1zbxNa+slTEHMdsMJi79/R 24c5gz9eSVjv9+w7lyKWG9ndormYGwyNE5U2ZnuvjKLA1dFTe0F1YtSfxuutbrrrYQGjdkupua3 UAci7E572GOrBxBBQPvEze7ymowhA3mxxRXX3GuDXSV4XkjzLIZqS7FTtcTtL0sg== X-Received: by 2002:a05:620a:178e:b0:912:67ca:bac6 with SMTP id af79cd13be357-9153d98adc6mr770549985a.26.1780179603772; Sat, 30 May 2026 15:20:03 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.20.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:20:03 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 12/13] selftests/liveupdate: Add stress-sessions kexec test Date: Sat, 30 May 2026 22:19:37 +0000 Message-ID: <20260530221938.115978-13-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new test that creates 2000 LUO sessions before a kexec reboot and verifies their presence after the reboot. This ensures that the linked-block serialization mechanism works correctly for a large number of sessions. Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav (Google) --- tools/testing/selftests/liveupdate/Makefile | 1 + .../liveupdate/luo_stress_sessions.c | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 tools/testing/selftests/liveupdate/luo_stress_sessions.c diff --git a/tools/testing/selftests/liveupdate/Makefile b/tools/testing/se= lftests/liveupdate/Makefile index 080754787ede..ed7534468386 100644 --- a/tools/testing/selftests/liveupdate/Makefile +++ b/tools/testing/selftests/liveupdate/Makefile @@ -6,6 +6,7 @@ TEST_GEN_PROGS +=3D liveupdate =20 TEST_GEN_PROGS_EXTENDED +=3D luo_kexec_simple TEST_GEN_PROGS_EXTENDED +=3D luo_multi_session +TEST_GEN_PROGS_EXTENDED +=3D luo_stress_sessions =20 TEST_FILES +=3D do_kexec.sh =20 diff --git a/tools/testing/selftests/liveupdate/luo_stress_sessions.c b/too= ls/testing/selftests/liveupdate/luo_stress_sessions.c new file mode 100644 index 000000000000..f201b1839d1d --- /dev/null +++ b/tools/testing/selftests/liveupdate/luo_stress_sessions.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin + * + * Validate that LUO can handle a large number of sessions across a kexec + * reboot. + */ + +#include +#include +#include "luo_test_utils.h" + +#define NUM_SESSIONS 2000 +#define STATE_SESSION_NAME "kexec_many_state" +#define STATE_MEMFD_TOKEN 999 + +/* Stage 1: Executed before the kexec reboot. */ +static void run_stage_1(int luo_fd) +{ + int ret, i; + + ksft_print_msg("[STAGE 1] Increasing ulimit for open files...\n"); + ret =3D luo_ensure_nofile_limit(NUM_SESSIONS); + if (ret =3D=3D -EPERM) + ksft_exit_skip("Insufficient privileges to set RLIMIT_NOFILE\n"); + if (ret < 0) + ksft_exit_fail_msg("luo_ensure_nofile_limit failed: %s\n", strerror(-ret= )); + + ksft_print_msg("[STAGE 1] Creating state file for next stage (2)...\n"); + create_state_file(luo_fd, STATE_SESSION_NAME, STATE_MEMFD_TOKEN, 2); + + ksft_print_msg("[STAGE 1] Creating %d sessions...\n", NUM_SESSIONS); + + for (i =3D 0; i < NUM_SESSIONS; i++) { + char name[LIVEUPDATE_SESSION_NAME_LENGTH]; + int s_fd; + + snprintf(name, sizeof(name), "many-test-%d", i); + s_fd =3D luo_create_session(luo_fd, name); + if (s_fd < 0) { + fail_exit("luo_create_session for '%s' at index %d", + name, i); + } + } + + ksft_print_msg("[STAGE 1] Successfully created %d sessions.\n", + NUM_SESSIONS); + + close(luo_fd); + daemonize_and_wait(); +} + +/* Stage 2: Executed after the kexec reboot. */ +static void run_stage_2(int luo_fd, int state_session_fd) +{ + int i, stage; + + ksft_print_msg("[STAGE 2] Starting post-kexec verification...\n"); + + restore_and_read_stage(state_session_fd, STATE_MEMFD_TOKEN, &stage); + if (stage !=3D 2) { + fail_exit("Expected stage 2, but state file contains %d", + stage); + } + + ksft_print_msg("[STAGE 2] Retrieving and finishing %d sessions...\n", + NUM_SESSIONS); + + for (i =3D 0; i < NUM_SESSIONS; i++) { + char name[LIVEUPDATE_SESSION_NAME_LENGTH]; + int s_fd; + + snprintf(name, sizeof(name), "many-test-%d", i); + s_fd =3D luo_retrieve_session(luo_fd, name); + if (s_fd < 0) { + fail_exit("luo_retrieve_session for '%s' at index %d", + name, i); + } + + if (luo_session_finish(s_fd) < 0) { + fail_exit("luo_session_finish for '%s' at index %d", + name, i); + } + close(s_fd); + } + + ksft_print_msg("[STAGE 2] Finalizing state session...\n"); + if (luo_session_finish(state_session_fd) < 0) + fail_exit("luo_session_finish for state session"); + close(state_session_fd); + + ksft_print_msg("\n--- MANY-SESSIONS KEXEC TEST PASSED (%d sessions) ---\n= ", + NUM_SESSIONS); +} + +int main(int argc, char *argv[]) +{ + return luo_test(argc, argv, STATE_SESSION_NAME, + run_stage_1, run_stage_2); +} --=20 2.53.0 From nobody Mon Jun 8 08:36:52 2026 Received: from mail-qk1-f175.google.com (mail-qk1-f175.google.com [209.85.222.175]) (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 83064379999 for ; Sat, 30 May 2026 22:20:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179608; cv=none; b=BRnuUoBNuXtp9/Dwh5PklFZB+QN2QK6mB8bjhFml8GoTU2mhJCFVVaHqBQ0zyLYMY3XeyUByKJPBiBn+SBIevH8RFz8qf0P0R2lkpkVd0HC/Dzm+RFdXOVvFAE2ajYMmfDuydlpwUkmcKU2SyHifvDbSXQprY9FwZhUJ5x9ilng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780179608; c=relaxed/simple; bh=PI26M0khAE7StCXBHeuwdUicbhLFrZpiZfsokDq9n88=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GRFL2+aVy+XSL4yxtJAl4YGaZ2HLxqULXeusH+3+kuHzhUn2JEfpaRmKDHT4mOPlSSscGeKYFnxlcvrgjUYB8lzTX7yR9hWDLA0XKLSMk/unJaFkyJ4Rt/+6W/5E0iufrr0hpPECTamoyVrqn+NemQOUy9PfTcE2pqNu3zPcDlE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=NyZMKQgY; arc=none smtp.client-ip=209.85.222.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="NyZMKQgY" Received: by mail-qk1-f175.google.com with SMTP id af79cd13be357-9154ca1aa1dso53052985a.0 for ; Sat, 30 May 2026 15:20:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1780179605; x=1780784405; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=LZ44uuKaEudMkx03Nujcoh6Uuv+6Qpcd4aVYSw8wkq4=; b=NyZMKQgYj9gZS3nJ3TwtHG7VqnqiDZ7KNKoh/6eimpM8dJG4qWT4jinWbbBmjb0PGx 3dSk/F5rGoQIor4+8DKMkZHq/U9EY7H7Yrt9RivbCT/Gee0N76YAwhFLRC+LOFl4qV5G rltSGcyOF+OCE8mydvhQLrM1hUhDpgXoXDccXZK3DdBhG/NwSEXt92AR3GHqXeCJ/6VP CaWI+kX00v3SZkCHNaxnGihKX78Og9V5jMk4TRFAIj5ahuTYS7I3oSpQGtXuvL5ETaoe 4dPeHjWVJ8g1+JBolFO6uVf4KnPuHu/C5g2+9+oC/kko3rrNwdTnZw51nSAHI5Oqe/co J6Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780179605; x=1780784405; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=LZ44uuKaEudMkx03Nujcoh6Uuv+6Qpcd4aVYSw8wkq4=; b=tXD9MmlNFJcwSvOuFTcsH2+grCVayZ2BFuWsKRbBlETGZ2edQQ+T2h63ZXVs0oS5Rt fPHYD8Waga1LqlPTOOSKtWl9vL4I2E8BxORBmSJJbmWnk+NaspKzMwjC3DgCKkqZPR81 HTqhI5OuYzLsAo2rrQMN51AuCe8z3S506r1r+XuLUOKTD9u5LovSflDc+Z8MjJFiGrUz OjR75kq+554p7FylqBeGXgyUDXrkDLol0sBYWfjowkFn9DxlwJ2cinH6RcBIzogl2Pr+ qmDj7JBH6EuMaWb/JzwWGZ5DOqifnEiSsvygFvjhg6kOzK8T2yRvbajAj1OBO84qhHq5 4GOQ== X-Forwarded-Encrypted: i=1; AFNElJ+gDy69g2LwgzijvbS4AinAm9ACJKQjodiz4hEt1CdDZDJHypNeijTKvQCOCj9CexAwSqu0sbPPhTZpb4k=@vger.kernel.org X-Gm-Message-State: AOJu0YxVEhkKTfJOSiWgaF1nWO/pOFBLG7YWhzFHbaaWgITs+wHQ45c8 TYJzG9wqV+2nqNF2KFNwNQk88d7EwOW9rfc/OBT+tKrywod95Bu6TLW+iP3pVd3JhM4= X-Gm-Gg: Acq92OEGoPtqgJ0HMq7GLnUrQ5RVhLKcEYakD5KyfW+011l6D9eMKyBZTCfSINesGFn bSkZnQ9l+zcCn33DKo8wdIy4DtzJz00IYrTbGvmuU1UABVjtZHAM3Q5p7UDf3ud2tsMMZXaXalp Biz3mQEf76dZXRnWxh1lNq56nFvwWk6k56wIQJ964AcW+35z0vEhgm143qjm2B7a4vU563URzi7 mNN2LZ4F+zvniXgpMxbjlIUO+cT9TDigvTAm5zAgFZPmortu7oPZ7Tx0dTamT4U6N1INcdKz3l4 Y8KyF2zKLkzOzYduV1voZgQeEuHMV+2MWDmvspawJ+oQDd880+KMAf5w1Nj6FHyfRoYFHebqHrc BfTVdaSb+eNSoHJCUUPdyZFSIKn/JB9ukgrtz3hylUaZcjbVLTtznFxh7sYXvHTdFmC6A7o9QkV SPTaGtOkdJiXbF+qDUyl2EmBGzet37qNy9TP3x11BDLiwDcHFP051KgLuRCYUAjw== X-Received: by 2002:a05:620a:29d5:b0:90f:786c:4a82 with SMTP id af79cd13be357-9152fa29820mr1006065185a.39.1780179605586; Sat, 30 May 2026 15:20:05 -0700 (PDT) Received: from plex ([71.181.43.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-915324868a0sm651790085a.18.2026.05.30.15.20.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 15:20:04 -0700 (PDT) From: Pasha Tatashin To: linux-kselftest@vger.kernel.org, rppt@kernel.org, shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org, skhan@linuxfoundation.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, corbet@lwn.net, pasha.tatashin@soleen.com, dmatlack@google.com, kexec@lists.infradead.org, pratyush@kernel.org, skhawaja@google.com, graf@amazon.com Subject: [PATCH v4 13/13] selftests/liveupdate: Add stress-files kexec test Date: Sat, 30 May 2026 22:19:38 +0000 Message-ID: <20260530221938.115978-14-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530221938.115978-1-pasha.tatashin@soleen.com> References: <20260530221938.115978-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new luo_stress_files kexec test that verifies preserving and retrieving 500 files across a kexec reboot. Reviewed-by: Pratyush Yadav (Google) Acked-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin --- tools/testing/selftests/liveupdate/Makefile | 1 + .../selftests/liveupdate/luo_stress_files.c | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 tools/testing/selftests/liveupdate/luo_stress_files.c diff --git a/tools/testing/selftests/liveupdate/Makefile b/tools/testing/se= lftests/liveupdate/Makefile index ed7534468386..30689d22cb02 100644 --- a/tools/testing/selftests/liveupdate/Makefile +++ b/tools/testing/selftests/liveupdate/Makefile @@ -7,6 +7,7 @@ TEST_GEN_PROGS +=3D liveupdate TEST_GEN_PROGS_EXTENDED +=3D luo_kexec_simple TEST_GEN_PROGS_EXTENDED +=3D luo_multi_session TEST_GEN_PROGS_EXTENDED +=3D luo_stress_sessions +TEST_GEN_PROGS_EXTENDED +=3D luo_stress_files =20 TEST_FILES +=3D do_kexec.sh =20 diff --git a/tools/testing/selftests/liveupdate/luo_stress_files.c b/tools/= testing/selftests/liveupdate/luo_stress_files.c new file mode 100644 index 000000000000..0cdf9cd4bac7 --- /dev/null +++ b/tools/testing/selftests/liveupdate/luo_stress_files.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin + * + * Validate that LUO can handle a large number of files per session across + * a kexec reboot. + */ + +#include +#include +#include "luo_test_utils.h" + +#define NUM_FILES 500 +#define STATE_SESSION_NAME "kexec_many_files_state" +#define STATE_MEMFD_TOKEN 9999 +#define TEST_SESSION_NAME "many_files_session" + +/* Stage 1: Executed before the kexec reboot. */ +static void run_stage_1(int luo_fd) +{ + int session_fd, i; + + ksft_print_msg("[STAGE 1] Creating state file for next stage (2)...\n"); + create_state_file(luo_fd, STATE_SESSION_NAME, STATE_MEMFD_TOKEN, 2); + + ksft_print_msg("[STAGE 1] Creating test session '%s'...\n", TEST_SESSION_= NAME); + session_fd =3D luo_create_session(luo_fd, TEST_SESSION_NAME); + if (session_fd < 0) + fail_exit("luo_create_session"); + + ksft_print_msg("[STAGE 1] Preserving %d files...\n", NUM_FILES); + for (i =3D 0; i < NUM_FILES; i++) { + char data[64]; + + snprintf(data, sizeof(data), "file-data-%d", i); + if (create_and_preserve_memfd(session_fd, i, data) < 0) + fail_exit("create_and_preserve_memfd for index %d", i); + } + + ksft_print_msg("[STAGE 1] Successfully preserved %d files.\n", NUM_FILES); + + close(luo_fd); + daemonize_and_wait(); +} + +/* Stage 2: Executed after the kexec reboot. */ +static void run_stage_2(int luo_fd, int state_session_fd) +{ + int session_fd; + int i, stage; + + ksft_print_msg("[STAGE 2] Starting post-kexec verification...\n"); + + restore_and_read_stage(state_session_fd, STATE_MEMFD_TOKEN, &stage); + if (stage !=3D 2) { + fail_exit("Expected stage 2, but state file contains %d", + stage); + } + + ksft_print_msg("[STAGE 2] Retrieving test session '%s'...\n", TEST_SESSIO= N_NAME); + session_fd =3D luo_retrieve_session(luo_fd, TEST_SESSION_NAME); + if (session_fd < 0) + fail_exit("luo_retrieve_session"); + + ksft_print_msg("[STAGE 2] Verifying %d files...\n", NUM_FILES); + for (i =3D 0; i < NUM_FILES; i++) { + char data[64]; + int fd; + + snprintf(data, sizeof(data), "file-data-%d", i); + fd =3D restore_and_verify_memfd(session_fd, i, data); + if (fd < 0) + fail_exit("restore_and_verify_memfd for index %d", i); + close(fd); + } + + ksft_print_msg("[STAGE 2] Finishing test session...\n"); + if (luo_session_finish(session_fd) < 0) + fail_exit("luo_session_finish for test session"); + close(session_fd); + + ksft_print_msg("[STAGE 2] Finalizing state session...\n"); + if (luo_session_finish(state_session_fd) < 0) + fail_exit("luo_session_finish for state session"); + close(state_session_fd); + + ksft_print_msg("\n--- MANY-FILES KEXEC TEST PASSED (%d files) ---\n", + NUM_FILES); +} + +int main(int argc, char *argv[]) +{ + return luo_test(argc, argv, STATE_SESSION_NAME, + run_stage_1, run_stage_2); +} --=20 2.53.0