From: Pratyush Yadav <pratyush@kernel.org>
To: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: linux-kselftest@vger.kernel.org, rppt@kernel.org,
shuah@kernel.org, akpm@linux-foundation.org,
linux-mm@kvack.org, vipinsh@google.com,
linux-kernel@vger.kernel.org, dmatlack@google.com,
kexec@lists.infradead.org, pratyush@kernel.org,
graf@amazon.com
Subject: Re: [PATCH v1 1/7] liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl to freeze sessions early
Date: Tue, 20 Oct 2026 13:08:14 +0200 [thread overview]
Message-ID: <2vxz8q3shboh.fsf@kernel.org> (raw)
In-Reply-To: <20261015093816.2438942-2-pasha.tatashin@soleen.com> (Pasha Tatashin's message of "Thu, 15 Oct 2026 05:38:10 -0400")
Hi,
On Thu, Oct 15 2026, Pasha Tatashin wrote:
> Currently, LUO sessions are frozen automatically only inside the
> reboot(LINUX_REBOOT_CMD_KEXEC) pathway, where luo_session_serialize()
> iterates through all outgoing sessions under global write locks and
> freezes them serially during shutdown. Allowing userspace to decide when
> to freeze a session once it is done with it (and to freeze multiple
> sessions in parallel, since luo_session_freeze() only acquires the
> per-session mutex) avoids postponing this work to kexec shutdown and
> reduces blackout time.
>
> Introduce LIVEUPDATE_SESSION_FREEZE on session file descriptors to freeze
> a session early. The ioctl runs .freeze() across all preserved files in the
> session and serializes their metadata. Once frozen, no additional files can
> be added to the session, and subsequent freeze calls return -EBUSY. Freeze
> is only valid on outgoing sessions and returns -EINVAL on incoming ones.
>
> During kexec, sessions that were already frozen early are skipped, while
> sessions that did not invoke this ioctl auto-freeze as before. If an
> early-frozen session is released before kexec, its files are rolled back
> via .unfreeze() before being unpreserved.
>
> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
[...]
> @@ -487,8 +488,10 @@ int luo_file_freeze(struct luo_file_set *file_set,
> file_ser->token = luo_file->token;
> }
>
> - file_set_ser->count = file_set->count;
> - file_set_ser->files = kho_block_set_head_pa(&file_set->block_set);
> + if (file_set_ser) {
> + file_set_ser->count = file_set->count;
> + file_set_ser->files = kho_block_set_head_pa(&file_set->block_set);
> + }
>
> return 0;
>
> @@ -501,7 +504,7 @@ int luo_file_freeze(struct luo_file_set *file_set,
> /**
> * luo_file_unfreeze - Unfreezes all files in a file_set and clear serialization
> * @file_set: The file_set whose files are to be unfrozen.
> - * @file_set_ser: Serialized file_set.
> + * @file_set_ser: Serialized file_set, or %NULL if not serialized yet.
> *
> * This function rolls back the state of all files in a file_set after the
> * freeze phase has begun but must be aborted. It is the counterpart to
> @@ -512,7 +515,8 @@ int luo_file_freeze(struct luo_file_set *file_set,
> * their respective .unfreeze() handler callbacks.
> *
> * Context: This is called when the live update is aborted during
> - * the reboot() syscall, after luo_file_freeze() has been called.
> + * the reboot() syscall, after luo_file_freeze() has been called,
> + * or when an early-frozen session is released before kexec.
> */
> void luo_file_unfreeze(struct luo_file_set *file_set,
> struct luo_file_set_ser *file_set_ser)
> @@ -521,7 +525,8 @@ void luo_file_unfreeze(struct luo_file_set *file_set,
> return;
>
> __luo_file_unfreeze(file_set, NULL);
> - memset(file_set_ser, 0, sizeof(*file_set_ser));
> + if (file_set_ser)
> + memset(file_set_ser, 0, sizeof(*file_set_ser));
> }
>
> /**
> diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h
> index 64879ffe73781..b42369c3b1f30 100644
> --- a/kernel/liveupdate/luo_internal.h
> +++ b/kernel/liveupdate/luo_internal.h
> @@ -64,6 +64,8 @@ struct luo_file_set {
> * previous kernel) sessions.
> * @retrieved: A boolean flag indicating whether this session has been
> * retrieved by a consumer in the new kernel.
> + * @frozen: A boolean flag indicating whether this session has been
> + * frozen early from userspace.
> * @file_set: A set of files that belong to this session.
> * @mutex: protects fields in the luo_session.
> */
> @@ -71,6 +73,7 @@ struct luo_session {
> char name[LIVEUPDATE_SESSION_NAME_LENGTH];
> struct list_head list;
> bool retrieved;
> + bool frozen;
> struct luo_file_set file_set;
> struct mutex mutex;
> };
> diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
> index f48e9a4185f97..403906937bc0f 100644
> --- a/kernel/liveupdate/luo_session.c
> +++ b/kernel/liveupdate/luo_session.c
> @@ -34,10 +34,11 @@
> * 1. Creation: A userspace agent calls `luo_session_create()` to create a
> * new, empty session and receives a file descriptor for it.
> *
> - * 2. Serialization: When the `reboot(LINUX_REBOOT_CMD_KEXEC)` syscall is
> - * made, `luo_session_serialize()` is called. It iterates through all
> - * active sessions and writes their metadata into a memory area preserved
> - * by KHO.
> + * 2. Freeze / Serialization: Sessions may be frozen early from userspace
> + * via `LIVEUPDATE_SESSION_FREEZE`. When the `reboot(LINUX_REBOOT_CMD_KEXEC)`
> + * syscall is made, `luo_session_serialize()` is called to freeze any
> + * remaining active sessions and write all session metadata into a memory
> + * area preserved by KHO.
> *
> * 3. Deserialization (in new kernel): After kexec, `luo_session_deserialize()`
> * runs, reading the serialized data and creating a list of `struct
> @@ -222,6 +223,10 @@ static void luo_session_unfreeze_one(struct luo_session *session,
> struct luo_session_ser *ser)
> {
> guard(mutex)(&session->mutex);
> + if (session->frozen) {
> + memset(&ser->file_set_ser, 0, sizeof(ser->file_set_ser));
> + return;
> + }
> luo_file_unfreeze(&session->file_set, &ser->file_set_ser);
> }
>
> @@ -229,6 +234,12 @@ static int luo_session_freeze_one(struct luo_session *session,
> struct luo_session_ser *ser)
> {
> guard(mutex)(&session->mutex);
> + if (session->frozen) {
> + ser->file_set_ser.count = session->file_set.count;
> + ser->file_set_ser.files =
> + kho_block_set_head_pa(&session->file_set.block_set);
> + return 0;
> + }
This is getting messy. If early freeze, then you set the file_set_ser
here, if late freeze, you set it in luo_file_freeze().
I think it is better to just set it here, and drop the code from
luo_file_freeze() entirely.
Same for unfreeze.
Maybe also rename the function to make it clear it only runs for
serialization? The core of serialization is done by luo_file_freeze().
> return luo_file_freeze(&session->file_set, &ser->file_set_ser);
> }
>
> @@ -249,8 +260,11 @@ static int luo_session_release(struct inode *inodep, struct file *filep)
> }
> sh = &luo_session_global.incoming;
> } else {
> - scoped_guard(mutex, &session->mutex)
> + scoped_guard(mutex, &session->mutex) {
> + if (session->frozen)
> + luo_file_unfreeze(&session->file_set, NULL);
> luo_file_unpreserve_files(&session->file_set);
> + }
> sh = &luo_session_global.outgoing;
> }
>
> @@ -267,6 +281,9 @@ static int luo_session_preserve_fd(struct luo_session *session,
> int err;
>
> guard(mutex)(&session->mutex);
> + if (session->frozen)
> + return -EBUSY;
> +
> err = luo_preserve_file(&session->file_set, argp->token, argp->fd);
> if (err)
> return err;
> @@ -340,11 +357,34 @@ static int luo_session_get_name(struct luo_session *session,
> return luo_ucmd_respond(ucmd, sizeof(*argp));
> }
>
> +static int luo_session_freeze(struct luo_session *session,
> + struct luo_ucmd *ucmd)
> +{
> + struct liveupdate_session_freeze *argp = ucmd->cmd;
> + int err;
> +
> + if (argp->reserved)
> + return -EINVAL;
> +
> + guard(mutex)(&session->mutex);
> + if (session->frozen)
> + return -EBUSY;
> +
> + err = luo_file_freeze(&session->file_set, NULL);
> + if (err)
> + return err;
> +
> + session->frozen = true;
> +
> + return luo_ucmd_respond(ucmd, sizeof(*argp));
> +}
> +
[...]
--
Regards,
Pratyush Yadav
next prev parent reply other threads:[~2026-10-20 11:08 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 9:38 [PATCH v1 0/7] liveupdate: tmpfs preservation and early freeze Pasha Tatashin
2026-10-15 9:38 ` [PATCH v1 1/7] liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl to freeze sessions early Pasha Tatashin
2026-10-15 9:47 ` sashiko-bot
2026-10-20 11:08 ` Pratyush Yadav [this message]
2026-10-20 14:30 ` Pasha Tatashin
2026-10-15 9:38 ` [PATCH v1 2/7] selftests: liveupdate: Add tests for LIVEUPDATE_SESSION_FREEZE Pasha Tatashin
2026-10-15 9:45 ` sashiko-bot
2026-10-15 9:38 ` [PATCH v1 3/7] liveupdate: Pass user argument to file preserve and retrieve Pasha Tatashin
2026-10-15 9:49 ` sashiko-bot
2026-10-19 19:26 ` tarunsahu
2026-10-19 19:31 ` Pasha Tatashin
2026-10-20 10:20 ` Pratyush Yadav
2026-10-15 9:38 ` [PATCH v1 4/7] selftests: liveupdate: Add tests for preserve and retrieve user argument Pasha Tatashin
2026-10-15 9:45 ` sashiko-bot
2026-10-15 9:38 ` [PATCH v1 5/7] liveupdate: Allow file handlers to mark retrieve failures as retryable Pasha Tatashin
2026-10-15 9:46 ` sashiko-bot
2026-10-15 9:38 ` [PATCH v1 6/7] mm/memfd_luo: Support tmpfs preservation and retrieval Pasha Tatashin
2026-10-15 9:54 ` sashiko-bot
2026-10-15 9:38 ` [PATCH v1 7/7] selftests: liveupdate: Add test coverage for " Pasha Tatashin
2026-10-15 9:47 ` sashiko-bot
2026-10-15 17:48 ` [PATCH v1 0/7] liveupdate: tmpfs preservation and early freeze David Matlack
2026-10-15 18:23 ` Pasha Tatashin
2026-10-15 18:54 ` David Matlack
2026-10-15 20:38 ` Pasha Tatashin
2026-10-15 21:53 ` David Matlack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2vxz8q3shboh.fsf@kernel.org \
--to=pratyush@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=dmatlack@google.com \
--cc=graf@amazon.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=pasha.tatashin@soleen.com \
--cc=rppt@kernel.org \
--cc=shuah@kernel.org \
--cc=vipinsh@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.