Re: [PATCH v9 4/5] liveupdate: luo_flb: Introduce File-Lifecycle-Bound global state
From: Pasha Tatashin
Date: Thu Mar 12 2026 - 21:04:51 EST
On Thu, Mar 12, 2026 at 7:59 PM David Matlack <dmatlack@xxxxxxxxxx> wrote:
>
> On Thu, Dec 18, 2025 at 7:58 AM Pasha Tatashin
> <pasha.tatashin@xxxxxxxxxx> wrote:
>
> > +static inline int liveupdate_register_flb(struct liveupdate_file_handler *fh,
> > + struct liveupdate_flb *flb)
> > +{
> > + return -EOPNOTSUPP;
> > +}
>
> I think LUO could use a cleanup to return 0 in all the register
> functions when Live Update is not enabled via CONFIG or parameter.
>
> I think all of the users of these functions are going to want to
> ignore -EOPNOTSUPP. memfd already does.
I would think EOPNOTSUPP is a standard return error when a feature is
not enabled. What if a component would need to do something different
by knowing that FLB is disabled and therefore perhaps it would also
skip some of LU related changes? I think it is a very minor think to
ignore EOPNOTSUPP when checking of other error types.
> > +static int luo_flb_retrieve_one(struct liveupdate_flb *flb)
> > +{
> > + struct luo_flb_private *private = luo_flb_get_private(flb);
> > + struct luo_flb_header *fh = &luo_flb_global.incoming;
> > + struct liveupdate_flb_op_args args = {0};
> > + bool found = false;
> > + int err;
> > +
> > + guard(mutex)(&private->incoming.lock);
> > +
> > + if (private->incoming.finished)
> > + return -ENODATA;
> > +
> > + if (private->incoming.retrieved)
> > + return 0;
> > +
> > + if (!fh->active)
> > + return -ENODATA;
> > +
> > + for (int i = 0; i < fh->header_ser->count; i++) {
> > + if (!strcmp(fh->ser[i].name, flb->compatible)) {
> > + private->incoming.data = fh->ser[i].data;
> > + private->incoming.count = fh->ser[i].count;
> > + found = true;
> > + break;
> > + }
> > + }
> > +
> > + if (!found)
> > + return -ENOENT;
>
> FLB users have no way to distinguish between "there was no data
> preserved" and "there was data preserved, but it was not a supported
> version".
Strictly speaking, FLB doesn't have a concept of "versions", it only
operates on compatible or incompatible data strings. If we find FLB
data but the compatible string doesn't match, we have no way of
knowing if that data was even intended for this specific handler.
> This is especially going to be important for PCI [1] since there's a
> big difference between "there were no devices preserved" and "there
> were devices preserved but the incoming kernel isn't compatible". The
If the incoming kernel does not find preserved device state, shouldn't
it just be treated as if no device state was preserved at all? In that
scenario, the subsystem would fall back to standard initialization and
simply reset the device state.
> former means there's nothing for the PCI subsystem to do wrt Live
> Update. The latter means we should probably panic the system.
>
> [1] https://lore.kernel.org/kvm/20260129212510.967611-3-dmatlack@xxxxxxxxxx/
>
> > +/**
> > + * liveupdate_unregister_flb - Remove an FLB dependency from a file handler.
> > + * @fh: The file handler that is currently depending on the FLB.
> > + * @flb: The File-Lifecycle-Bound object to remove.
> > + *
> > + * Removes the association between the specified file handler and the FLB
> > + * previously established by liveupdate_register_flb().
> > + *
> > + * This function manages the global lifecycle of the FLB. It decrements the
> > + * FLB's usage count. If this was the last file handler referencing this FLB,
> > + * the FLB is removed from the global registry and the reference to its
> > + * owner module (acquired during registration) is released.
> > + *
> > + * Context: This function ensures the session is quiesced (no active FDs
> > + * being created) during the update. It is typically called from a
> > + * subsystem's module exit function.
> > + * Return: 0 on success.
> > + * -EOPNOTSUPP if live update is disabled.
> > + * -EBUSY if the live update session is active and cannot be quiesced.
> > + * -ENOENT if the FLB was not found in the file handler's list.
> > + */
> > +int liveupdate_unregister_flb(struct liveupdate_file_handler *fh,
> > + struct liveupdate_flb *flb)
>
> Alex Williamson and Jason Gunthrope both suggested this should return void.
>
> https://lore.kernel.org/kvm/20260303210733.GG972761@xxxxxxxxxx/
>
> I suspect liveupdate_unregister_file_handler() should as well. I don't
> think there's anything callers can do if unregister fails.
Thank you for the heads-up; I replied in that thread. We can clean-up
some of the return erros, but I am not sure what to do about -EBUSY.
Pasha