From: Mike Rapoport <rppt@kernel.org>
To: David Matlack <dmatlack@google.com>,
Luca Boccassi <luca.boccassi@gmail.com>
Cc: kexec@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org, Jason Gunthorpe <jgg@nvidia.com>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Pratyush Yadav <pratyush@kernel.org>,
Samiullah Khawaja <skhawaja@google.com>,
Shuah Khan <shuah@kernel.org>
Subject: Re: [RFC PATCH] liveupdate: Allow multiple openers for /dev/liveupdate
Date: Thu, 16 Jul 2026 09:06:53 +0300 [thread overview]
Message-ID: <alh0_aCbZITvSaox@kernel.org> (raw)
In-Reply-To: <20260714190356.190328-1-dmatlack@google.com>
(adding Luca for systemd POV)
On Tue, Jul 14, 2026 at 07:03:56PM +0000, David Matlack wrote:
> Remove the single-opener restriction for /dev/liveupdate by removing the
> atomic in_use tracking and the exclusive open check in luo_open() that
> returned -EBUSY. Protect luo_session_deserialize() with a mutex guard so
> that concurrent open attempts by multiple processes safely executes
> deserialization only once. Update liveupdate selftest to verify that
> multiple concurrent openers succeed.
>
> LUO does not inherently require a single opener. There is some
> documentation about it simplifying state management, but the only thing
> it actually protects is the session deserialization during first open,
> which can be easily handled with a mutex.
>
> Relaxing the single-opener requirement avoids the kernel forcing a
> design pattern on userspace that it itself does not require, e.g.
> allowing multiple userspace processes to create and manage sessions.
>
> Signed-off-by: David Matlack <dmatlack@google.com>
> ---
> Cc: Jason Gunthorpe <jgg@nvidia.com>
> Cc: Samiullah Khawaja <skhawaja@google.com>
>
> kernel/liveupdate/luo_core.c | 46 +++----------------
> kernel/liveupdate/luo_session.c | 8 +++-
> .../testing/selftests/liveupdate/liveupdate.c | 14 +++---
> 3 files changed, 18 insertions(+), 50 deletions(-)
>
> diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c
> index 1b2bda22902d..931bb79da276 100644
> --- a/kernel/liveupdate/luo_core.c
> +++ b/kernel/liveupdate/luo_core.c
> @@ -254,19 +254,8 @@ bool liveupdate_enabled(void)
> * which allows a userspace agent to manage the LUO state machine and its
> * associated resources, such as preservable file descriptors.
> *
> - * To ensure that the state machine is controlled by a single entity, access
> - * to this device is exclusive: only one process is permitted to have
> - * ``/dev/liveupdate`` open at any given time. Subsequent open attempts will
> - * fail with -EBUSY until the first process closes its file descriptor.
> - * This singleton model simplifies state management by preventing conflicting
> - * commands from multiple userspace agents.
> */
>
> -struct luo_device_state {
> - struct miscdevice miscdev;
> - atomic_t in_use;
> -};
> -
> static int luo_ioctl_create_session(struct luo_ucmd *ucmd)
> {
> struct liveupdate_ioctl_create_session *argp = ucmd->cmd;
> @@ -329,28 +318,9 @@ static int luo_ioctl_retrieve_session(struct luo_ucmd *ucmd)
>
> static int luo_open(struct inode *inodep, struct file *filep)
> {
> - struct luo_device_state *ldev = container_of(filep->private_data,
> - struct luo_device_state,
> - miscdev);
> -
> - if (atomic_cmpxchg(&ldev->in_use, 0, 1))
> - return -EBUSY;
> -
> /* Always return -EIO to user if deserialization fail */
> - if (luo_session_deserialize()) {
> - atomic_set(&ldev->in_use, 0);
> + if (luo_session_deserialize())
> return -EIO;
> - }
> -
> - return 0;
> -}
> -
> -static int luo_release(struct inode *inodep, struct file *filep)
> -{
> - struct luo_device_state *ldev = container_of(filep->private_data,
> - struct luo_device_state,
> - miscdev);
> - atomic_set(&ldev->in_use, 0);
>
> return 0;
> }
> @@ -419,17 +389,13 @@ static long luo_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
> static const struct file_operations luo_fops = {
> .owner = THIS_MODULE,
> .open = luo_open,
> - .release = luo_release,
> .unlocked_ioctl = luo_ioctl,
> };
>
> -static struct luo_device_state luo_dev = {
> - .miscdev = {
> - .minor = MISC_DYNAMIC_MINOR,
> - .name = "liveupdate",
> - .fops = &luo_fops,
> - },
> - .in_use = ATOMIC_INIT(0),
> +static struct miscdevice luo_dev = {
> + .minor = MISC_DYNAMIC_MINOR,
> + .name = "liveupdate",
> + .fops = &luo_fops,
> };
>
> static int __init liveupdate_ioctl_init(void)
> @@ -437,6 +403,6 @@ static int __init liveupdate_ioctl_init(void)
> if (!liveupdate_enabled())
> return 0;
>
> - return misc_register(&luo_dev.miscdev);
> + return misc_register(&luo_dev);
> }
> late_initcall(liveupdate_ioctl_init);
> diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
> index b79b2a488974..ca4d0639d39a 100644
> --- a/kernel/liveupdate/luo_session.c
> +++ b/kernel/liveupdate/luo_session.c
> @@ -584,13 +584,17 @@ static int luo_session_deserialize_one(struct luo_session_header *sh,
>
> int luo_session_deserialize(void)
> {
> - struct luo_session_header *sh = &luo_session_global.incoming;
> + static DEFINE_MUTEX(luo_session_deserialize_lock);
> static bool is_deserialized;
> + static int saved_err;
> +
> + struct luo_session_header *sh = &luo_session_global.incoming;
> struct luo_session_ser *ser;
> struct kho_block_set_it it;
> - static int saved_err;
> int err;
>
> + guard(mutex)(&luo_session_deserialize_lock);
> +
> /* If has been deserialized, always return the same error code */
> if (is_deserialized)
> return saved_err;
> diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testing/selftests/liveupdate/liveupdate.c
> index 502fb3567e38..a8e1a8911849 100644
> --- a/tools/testing/selftests/liveupdate/liveupdate.c
> +++ b/tools/testing/selftests/liveupdate/liveupdate.c
> @@ -11,7 +11,7 @@
> * /dev/liveupdate character device and its session management capabilities.
> *
> * Tests include:
> - * - Device access: basic open/close, and enforcement of exclusive access.
> + * - Device access: basic open/close, and support for multiple openers.
> * - Session management: creation of unique sessions, and duplicate name detection.
> * - Resource preservation: successfully preserving individual and multiple memfds,
> * verifying contents remain accessible.
> @@ -70,13 +70,12 @@ TEST_F(liveupdate_device, basic_open_close)
> }
>
> /*
> - * Test Case: Exclusive Open Enforcement
> + * Test Case: Multiple Open Support
> *
> - * Verifies that the /dev/liveupdate device can only be opened by one process
> - * at a time. It checks that a second attempt to open the device fails with
> - * the EBUSY error code.
> + * Verifies that the /dev/liveupdate device can be opened by multiple openers
> + * concurrently without errors.
> */
> -TEST_F(liveupdate_device, exclusive_open)
> +TEST_F(liveupdate_device, multiple_open)
> {
> self->fd1 = open(LIVEUPDATE_DEV, O_RDWR);
>
> @@ -85,8 +84,7 @@ TEST_F(liveupdate_device, exclusive_open)
>
> ASSERT_GE(self->fd1, 0);
> self->fd2 = open(LIVEUPDATE_DEV, O_RDWR);
> - EXPECT_LT(self->fd2, 0);
> - EXPECT_EQ(errno, EBUSY);
> + ASSERT_GE(self->fd2, 0);
> }
>
> /* Helper function to create a LUO session via ioctl. */
>
> base-commit: 10fd52dc7bbd6013e949ff1833be0821b7553fb0
> --
> 2.55.0.141.g00534a21ce-goog
>
--
Sincerely yours,
Mike.
prev parent reply other threads:[~2026-07-16 6:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 19:03 [RFC PATCH] liveupdate: Allow multiple openers for /dev/liveupdate David Matlack
2026-07-15 13:50 ` Pratyush Yadav
2026-07-15 16:07 ` David Matlack
2026-07-15 17:23 ` Jason Gunthorpe
2026-07-16 6:06 ` Mike Rapoport [this message]
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=alh0_aCbZITvSaox@kernel.org \
--to=rppt@kernel.org \
--cc=dmatlack@google.com \
--cc=jgg@nvidia.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=luca.boccassi@gmail.com \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=shuah@kernel.org \
--cc=skhawaja@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox