Re: [PATCH v8 10/12] PCI: liveupdate: Freeze preservation status during shutdown

From: David Matlack

Date: Thu Sep 17 2026 - 19:38:47 EST


On 2026-09-17 03:17 PM, Bjorn Helgaas wrote:
> On Tue, Jul 28, 2026 at 10:10:04PM +0000, David Matlack wrote:
> > Freeze a device's outgoing preservation status (preserved or not
> > preserved) during shutdown. This enables the PCI core and drivers to
> > safely make decisions based on the device's preservation status during
> > shutdown.
> >
> > Note that pci_liveupdate_freeze() is triggered by the PCI core rather
> > than from drivers participating in Live Update so that all devices can
> > have their status frozen (i.e. prevent non-preserved devices from
> > getting preserved late).
>
> This calls pci_liveupdate_freeze() from pci_device_shutdown(), the
> pci_bus_type .shutdown() method, which I think is only called from
> device_shutdown() in the kexec or restart paths.
>
> Since there's no error exit after we get as far as device_shutdown(),
> and this applies to all devices and dev->liveupdate.frozen is never
> set to false (at least at this point in the series), is there benefit
> to tracking this per-device?

I think this could be global. But I don't see any obvious place to add
that hook and keeping it per device is one less global variable to
worry about.

> > Reviewed-by: Pranjal Shrivastava <praan@xxxxxxxxxx>
> > Reviewed-by: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>
> > Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
>
> Reviewed-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
>
> > ---
> > drivers/pci/liveupdate.c | 16 ++++++++++++++++
> > drivers/pci/liveupdate.h | 4 ++++
> > drivers/pci/pci-driver.c | 2 ++
> > include/linux/pci_liveupdate.h | 3 +++
> > 4 files changed, 25 insertions(+)
> >
> > diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> > index 744513ee11ed..65bcecb1b64e 100644
> > --- a/drivers/pci/liveupdate.c
> > +++ b/drivers/pci/liveupdate.c
> > @@ -394,6 +394,11 @@ static int pci_liveupdate_unpreserve_device(struct pci_flb_outgoing *outgoing,
> > {
> > struct pci_dev_ser *dev_ser = dev->liveupdate.outgoing;
> >
> > + if (dev->liveupdate.frozen) {
> > + pci_warn(dev, "Cannot unpreserve device after it is frozen!\n");
> > + return -EINVAL;
> > + }
> > +
> > if (!dev_ser) {
> > pci_warn(dev, "Cannot unpreserve device that is not preserved\n");
> > return -EINVAL;
> > @@ -447,6 +452,11 @@ static int pci_liveupdate_preserve_device(struct pci_flb_outgoing *outgoing,
> > return -EINVAL;
> > }
> >
> > + if (dev->liveupdate.frozen) {
> > + pci_warn(dev, "Cannot preserve device after it is frozen!\n");
> > + return -EINVAL;
> > + }
> > +
> > if (dev->liveupdate.outgoing) {
> > if (!dev->liveupdate.outgoing->refcount) {
> > pci_WARN(dev, 1, "Preserved device with 0 refcount!\n");
> > @@ -718,6 +728,12 @@ void pci_liveupdate_cleanup_device(struct pci_dev *dev)
> > pci_WARN(dev, 1, "Destroying incoming-preserved device!\n");
> > }
> >
> > +void pci_liveupdate_freeze(struct pci_dev *dev)
> > +{
> > + guard(rwsem_write)(&pci_liveupdate.rwsem);
> > + dev->liveupdate.frozen = 1;
>
> Nit, the series assigns "true" to other booleans
> (preserve_bus_numbers, was_preserved).

Ack, will fix.