[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CA+CK2bDSSJhjx8fH1rsb3unS099pKWze-=WX1B2ZnE0LCMXUAw@mail.gmail.com>
Date: Fri, 21 Nov 2025 16:30:46 -0500
From: Pasha Tatashin <pasha.tatashin@...een.com>
To: Pratyush Yadav <pratyush@...nel.org>
Cc: jasonmiu@...gle.com, graf@...zon.com, rppt@...nel.org, dmatlack@...gle.com,
rientjes@...gle.com, corbet@....net, rdunlap@...radead.org,
ilpo.jarvinen@...ux.intel.com, kanie@...ux.alibaba.com, ojeda@...nel.org,
aliceryhl@...gle.com, masahiroy@...nel.org, akpm@...ux-foundation.org,
tj@...nel.org, yoann.congal@...le.fr, mmaurer@...gle.com,
roman.gushchin@...ux.dev, chenridong@...wei.com, axboe@...nel.dk,
mark.rutland@....com, jannh@...gle.com, vincent.guittot@...aro.org,
hannes@...xchg.org, dan.j.williams@...el.com, david@...hat.com,
joel.granados@...nel.org, rostedt@...dmis.org, anna.schumaker@...cle.com,
song@...nel.org, linux@...ssschuh.net, linux-kernel@...r.kernel.org,
linux-doc@...r.kernel.org, linux-mm@...ck.org, gregkh@...uxfoundation.org,
tglx@...utronix.de, mingo@...hat.com, bp@...en8.de,
dave.hansen@...ux.intel.com, x86@...nel.org, hpa@...or.com, rafael@...nel.org,
dakr@...nel.org, bartosz.golaszewski@...aro.org, cw00.choi@...sung.com,
myungjoo.ham@...sung.com, yesanishhere@...il.com, Jonathan.Cameron@...wei.com,
quic_zijuhu@...cinc.com, aleksander.lobakin@...el.com, ira.weiny@...el.com,
andriy.shevchenko@...ux.intel.com, leon@...nel.org, lukas@...ner.de,
bhelgaas@...gle.com, wagi@...nel.org, djeffery@...hat.com,
stuart.w.hayes@...il.com, lennart@...ttering.net, brauner@...nel.org,
linux-api@...r.kernel.org, linux-fsdevel@...r.kernel.org, saeedm@...dia.com,
ajayachandra@...dia.com, jgg@...dia.com, parav@...dia.com, leonro@...dia.com,
witu@...dia.com, hughd@...gle.com, skhawaja@...gle.com, chrisl@...nel.org
Subject: Re: [PATCH v6 04/20] liveupdate: luo_session: add sessions support
> > /*
> > * The LUO FDT hooks all LUO state for sessions, fds, etc.
> > - * In the root it allso carries "liveupdate-number" 64-bit property that
> > + * In the root it also carries "liveupdate-number" 64-bit property that
>
> Nit: This needs a bit of patch massaging. Patch 2 added the typo, and
> this patch fixes it. It would be better to just update patch 2.
Yeap, this is fixed.
> > + * 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.
> > + */
> > +struct luo_session_header_ser {
> > + u64 pgcnt;
>
> Why do you need pgcnt here? Can't the size be inferred from count? And
> since you use contiguous memory block, the folio will know its page
> count anyway, right? The less we have in the ABI the better IMO.
Right, I had pgnct because my allocators were using size as an
argument, but we removed that, so pgcnt can also be removed.
> Same for other structures below.
>
> > + u64 count;
> > +} __packed;
> > +
> > +/**
> > + * struct luo_session_ser - Represents the serialized metadata for a LUO session.
> > + * @name: The unique name of the session, copied from the `luo_session`
> > + * structure.
> > + * @files: The physical address of a contiguous memory block that holds
> > + * the serialized state of files.
> > + * @pgcnt: The number of pages occupied by the `files` memory block.
> > + * @count: The total number of files that were part of this session during
> > + * serialization. Used for iteration and validation during
> > + * restoration.
> > + *
> > + * This structure is used to package session-specific metadata for transfer
> > + * between kernels via Kexec Handover. An array of these structures (one per
> > + * session) is created and passed to the new kernel, allowing it to reconstruct
> > + * the session context.
> > + *
> > + * If this structure is modified, LUO_SESSION_COMPATIBLE must be updated.
> > + */
> > +struct luo_session_ser {
> > + char name[LIVEUPDATE_SESSION_NAME_LENGTH];
> > + u64 files;
> > + u64 pgcnt;
> > + u64 count;
> > +} __packed;
> > +
> > #endif /* _LINUX_LIVEUPDATE_ABI_LUO_H */
> [...]
> > +/* Create a "struct file" for session */
> > +static int luo_session_getfile(struct luo_session *session, struct file **filep)
> > +{
> > + char name_buf[128];
> > + struct file *file;
> > +
> > + guard(mutex)(&session->mutex);
> > + snprintf(name_buf, sizeof(name_buf), "[luo_session] %s", session->name);
> > + file = anon_inode_getfile(name_buf, &luo_session_fops, session, O_RDWR);
>
> Nit: You can return the file directly and get rid of filep.
I prefer returning error here.
>
> > + if (IS_ERR(file))
> > + return PTR_ERR(file);
> > +
> > + *filep = file;
> > +
> > + return 0;
> > +}
> [...]
> > +int __init luo_session_setup_outgoing(void *fdt_out)
> > +{
> > + struct luo_session_header_ser *header_ser;
> > + u64 header_ser_pa;
> > + int err;
> > +
> > + header_ser = kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT);
>
> Nit: The naming is a bit confusing here. At first glance I thought this
> was just allocating the header, but it allocates the whole session
> serialization buffer.
I made it a little clearer by adding "outgoing_buffer" local variable,
and then assigning head_ser to this local variable.
> > + if (IS_ERR(header_ser))
> > + return PTR_ERR(header_ser);
> > + header_ser_pa = virt_to_phys(header_ser);
> > +
> > + err = fdt_begin_node(fdt_out, LUO_FDT_SESSION_NODE_NAME);
> > + err |= fdt_property_string(fdt_out, "compatible",
> > + LUO_FDT_SESSION_COMPATIBLE);
> > + err |= fdt_property(fdt_out, LUO_FDT_SESSION_HEADER, &header_ser_pa,
> > + sizeof(header_ser_pa));
> > + err |= fdt_end_node(fdt_out);
> > +
> > + if (err)
> > + goto err_unpreserve;
> > +
> > + header_ser->pgcnt = LUO_SESSION_PGCNT;
> > + INIT_LIST_HEAD(&luo_session_global.outgoing.list);
> > + init_rwsem(&luo_session_global.outgoing.rwsem);
> > + luo_session_global.outgoing.header_ser = header_ser;
> > + luo_session_global.outgoing.ser = (void *)(header_ser + 1);
> > + luo_session_global.outgoing.active = true;
> > +
> > + return 0;
> > +
> > +err_unpreserve:
> > + kho_unpreserve_free(header_ser);
> > + return err;
> > +}
> [...]
> > +int luo_session_deserialize(void)
> > +{
> > + struct luo_session_header *sh = &luo_session_global.incoming;
> > + int err;
> > +
> > + if (luo_session_is_deserialized())
> > + return 0;
> > +
> > + luo_session_global.deserialized = true;
> > + if (!sh->active) {
> > + INIT_LIST_HEAD(&sh->list);
> > + init_rwsem(&sh->rwsem);
>
> Nit: it would be a bit simpler if LUO init always initialized this. And
> then luo_session_setup_incoming() can fill the list if it has any data.
> Slight reduction in code duplication and mental load.
These are now statically initialized.
>
> > + return 0;
> > + }
> > +
> > + for (int i = 0; i < sh->header_ser->count; i++) {
> > + struct luo_session *session;
> > +
> > + session = luo_session_alloc(sh->ser[i].name);
> > + if (IS_ERR(session)) {
> > + pr_warn("Failed to allocate session [%s] during deserialization %pe\n",
> > + sh->ser[i].name, session);
> > + return PTR_ERR(session);
> > + }
> > +
> > + err = luo_session_insert(sh, session);
> > + if (err) {
> > + luo_session_free(session);
> > + pr_warn("Failed to insert session [%s] %pe\n",
> > + session->name, ERR_PTR(err));
> > + return err;
> > + }
> > +
> > + session->count = sh->ser[i].count;
> > + session->files = sh->ser[i].files ? phys_to_virt(sh->ser[i].files) : 0;
> > + session->pgcnt = sh->ser[i].pgcnt;
> > + }
> > +
> > + kho_restore_free(sh->header_ser);
> > + sh->header_ser = NULL;
> > + sh->ser = NULL;
> > +
> > + return 0;
> > +}
> [...]
>
> --
> Regards,
> Pratyush Yadav
Thanks!
Pasha
Powered by blists - more mailing lists