From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 03114FF8860 for ; Mon, 27 Apr 2026 15:57:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Subject:Cc:To: From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=9LeH8B86nKcZOpLZaBsejYDxB8jSKUcx+rF/bpcYhS4=; b=atfKrqOZmsJjvYqo5CoP19XC68 GrssSsNYghLMQg/jXGjNHwyIWfcKrkVKQuMJEIsSTTX+0iSThE/IaqhSWmXGaMPn9H40Jd73TeSV5 wJvKM0fcKbEzEM0cS5Ae29NOYELgm22Q0Cg2F0ZlrXyL6yl5zOwDeWjrQN9RS5lFTAeOT3dHAdnpQ LMpWYlRZ8L2C4598kgC0VNWhFQ5/gpn0QqRhZmFR0LXjkkj6/O+f0CIEBrMKRekaTH12iu1LJTcp5 X5IWFosnVsnuySZidxBFKPI2eWYXsiq8zT3daXsDKudLAjXDDR4qaRgMHfFec1d3w1uciAMPtpfg+ gZ09SIIQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wHOL3-0000000HFs3-2SSV; Mon, 27 Apr 2026 15:57:37 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wHOL1-0000000HFrL-1Xdi for kexec@bombadil.infradead.org; Mon, 27 Apr 2026 15:57:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:Content-Type :MIME-Version:References:In-Reply-To:Message-ID:Subject:Cc:To:From:Date: Sender:Reply-To:Content-ID:Content-Description; bh=9LeH8B86nKcZOpLZaBsejYDxB8jSKUcx+rF/bpcYhS4=; b=QNW9iK/hQiy1Q9ZKpWv+JSuOD1 SsPbntofs70HcMq+8WNn6Azz5z/U9WJlEKUCmEOHUkAz7EdStUmM/ObMD0R+lkRUHLB4O+XOe/t7m 7eO6wIfRV402oDEfFLIaHgtnenqUSb37DKyvSfctj7frJzJaQJxatI6PQTXe2KvzPpLfT9yVP5dmN ZvLpigb5zvj8q/q4rWplBT9s0tbQ+itkV/nfwmkvtHv34k4f7b1kwGxUIcJWkKVZRE4zM6tLurGLK 0JbWto5zDoQHiM/8YZ2BFucli2pigg9F4ntdz2W5aI80R5hGDR0+f0Mx6DPwmnZgXeINONW5J3pSg ep6+Fepg==; Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wHOKy-000000012br-28PQ for kexec@lists.infradead.org; Mon, 27 Apr 2026 15:57:34 +0000 Received: from localhost (unknown [40.65.108.177]) by linux.microsoft.com (Postfix) with ESMTPSA id D338920B716A; Mon, 27 Apr 2026 08:57:27 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D338920B716A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1777305448; bh=9LeH8B86nKcZOpLZaBsejYDxB8jSKUcx+rF/bpcYhS4=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=OhQoS5cTppvzXia529YlPHyl3gEpjLWlCpqEjC0wytPu1aoMn+auy5b+Twna7AZOq Lvng4260i2n0yzHjGfSp5eYpSAvQTyiXS2IYISChFXvH/uD1Pd2GiYxD6n9fpiMfwn a+1mc9wLudzyJ4EU5tC+TsVbZknBuN1SpzNpVqY8= Date: Mon, 27 Apr 2026 08:57:25 -0700 From: Jacob Pan To: David Matlack Cc: iommu@lists.linux.dev, kexec@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-pci@vger.kernel.org, Adithya Jayachandran , Alexander Graf , Alex Williamson , Bjorn Helgaas , Chris Li , David Rientjes , Jason Gunthorpe , Joerg Roedel , Jonathan Corbet , Josh Hilke , Leon Romanovsky , Lukas Wunner , Mike Rapoport , Parav Pandit , Pasha Tatashin , Pranjal Shrivastava , Pratyush Yadav , Robin Murphy , Saeed Mahameed , Samiullah Khawaja , Shuah Khan , Will Deacon , William Tu , Yi Liu Subject: Re: [PATCH v4 02/11] PCI: liveupdate: Track outgoing preserved PCI devices Message-ID: <20260427085725.00005283@linux.microsoft.com> In-Reply-To: <20260423212316.3431746-3-dmatlack@google.com> References: <20260423212316.3431746-1-dmatlack@google.com> <20260423212316.3431746-3-dmatlack@google.com> Organization: LSG X-Mailer: Claws Mail 3.21.0 (GTK+ 2.24.33; x86_64-w64-mingw32) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260427_165732_799805_DDC42C35 X-CRM114-Status: GOOD ( 39.58 ) X-BeenThere: kexec@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kexec" Errors-To: kexec-bounces+kexec=archiver.kernel.org@lists.infradead.org Hi David, On Thu, 23 Apr 2026 21:23:06 +0000 David Matlack wrote: > Add APIs to allow drivers to notify the PCI core of which devices are > being preserved across a Live Update for the next kernel, i.e. > "outgoing" devices. > > Drivers must notify the PCI core when devices are preserved so that > the PCI core can update its FLB data (struct pci_ser) and track the > list of outgoing devices. pci_liveupdate_preserve() notifies the PCI > core that a device must be preserved across Live Update. > pci_liveupdate_unpreserve() reverses this (cancels the preservation > of the device). > > This tracking ensures the PCI core is fully aware of which devices may > need special handling during shutdown and kexec, and so that it can be > handed off to the next kernel. > > Signed-off-by: David Matlack > --- > drivers/pci/liveupdate.c | 101 > ++++++++++++++++++++++++++++++++++++ include/linux/kho/abi/pci.h | > 7 +-- include/linux/pci.h | 26 ++++++++++ > 3 files changed, 131 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c > index d4fa61625d56..2dd8daa2f17c 100644 > --- a/drivers/pci/liveupdate.c > +++ b/drivers/pci/liveupdate.c > @@ -43,6 +43,26 @@ > * > * * ``pci_liveupdate_register_flb(driver_file_handler)`` > * * ``pci_liveupdate_unregister_flb(driver_file_handler)`` > + * > + * Device Tracking > + * =============== > + * > + * Drivers must notify the PCI core when specific devices are > preserved or > + * unpreserved with the following APIs: > + * > + * * ``pci_liveupdate_preserve(pci_dev)`` > + * * ``pci_liveupdate_unpreserve(pci_dev)`` > + * > + * This allows the PCI core to keep it's FLB data (struct pci_ser) > up to date > + * with the list of **outgoing** preserved devices for the next > kernel. > + * > + * Restrictions > + * ============ > + * > + * The PCI core enforces the following restrictions on which devices > can be > + * preserved. These may be relaxed in the future: > + * > + * * The device cannot be a Virtual Function (VF). > */ > > #define pr_fmt(fmt) "PCI: liveupdate: " fmt > @@ -57,6 +77,8 @@ > #include > #include > > +static DEFINE_MUTEX(pci_flb_outgoing_lock); > + > static int pci_flb_preserve(struct liveupdate_flb_op_args *args) > { > struct pci_dev *dev = NULL; > @@ -124,6 +146,85 @@ static struct liveupdate_flb pci_liveupdate_flb > = { .compatible = PCI_LUO_FLB_COMPATIBLE, > }; > > +int pci_liveupdate_preserve(struct pci_dev *dev) > +{ > + struct pci_ser *ser; > + int i, ret; > + > + guard(mutex)(&pci_flb_outgoing_lock); > + > + ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void > **)&ser); > + if (ret) > + return ret; > + > + if (!ser) > + return -ENOENT; > + > + if (dev->is_virtfn) > + return -EINVAL; This can be left outside the mutex? > + > + if (dev->liveupdate_outgoing) > + return -EBUSY; > + > + if (ser->nr_devices == ser->max_nr_devices) > + return -ENOSPC; > + > + for (i = 0; i < ser->max_nr_devices; i++) { > + /* > + * Start searching at index ser->nr_devices. This > should result > + * in a constant time search under expected > conditions (devices > + * are not getting unpreserved). > + */ > + int index = (ser->nr_devices + i) % > ser->max_nr_devices; > + struct pci_dev_ser *dev_ser = &ser->devices[index]; > + > + if (dev_ser->refcount) > + continue; > + > + pci_info(dev, "Device will be preserved across next > Live Update\n"); > + ser->nr_devices++; > + > + dev_ser->domain = pci_domain_nr(dev->bus); > + dev_ser->bdf = pci_dev_id(dev); > + dev_ser->refcount = 1; > + > + dev->liveupdate_outgoing = dev_ser; > + return 0; > + } > + > + return -ENOSPC; > +} > +EXPORT_SYMBOL_GPL(pci_liveupdate_preserve); > + > +void pci_liveupdate_unpreserve(struct pci_dev *dev) > +{ > + struct pci_dev_ser *dev_ser; > + struct pci_ser *ser = NULL; > + int ret; > + > + guard(mutex)(&pci_flb_outgoing_lock); > + > + ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void > **)&ser); + > + if (ret || !ser) { > + pci_warn(dev, "Cannot unpreserve device without > outgoing Live Update state\n"); > + return; > + > + } > + > + dev_ser = dev->liveupdate_outgoing; > + if (!dev_ser) { > + pci_warn(dev, "Cannot unpreserve device that is not > preserved\n"); > + return; > + } > + > + pci_info(dev, "Device will no longer be preserved across > next Live Update\n"); > + ser->nr_devices--; > + memset(dev_ser, 0, sizeof(*dev_ser)); > + dev->liveupdate_outgoing = NULL; > +} > +EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve); > + > int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh) > { > pr_debug("Registering file handler \"%s\"\n", > fh->compatible); diff --git a/include/linux/kho/abi/pci.h > b/include/linux/kho/abi/pci.h index 5c0e92588c00..5b4c8d9e462c 100644 > --- a/include/linux/kho/abi/pci.h > +++ b/include/linux/kho/abi/pci.h > @@ -23,19 +23,20 @@ > * incrementing the version number in the PCI_LUO_FLB_COMPATIBLE > string. */ > > -#define PCI_LUO_FLB_COMPATIBLE "pci-v1" > +#define PCI_LUO_FLB_COMPATIBLE "pci-v2" > > /** > * struct pci_dev_ser - Serialized state about a single PCI device. > * > * @domain: The device's PCI domain number (segment). > * @bdf: The device's PCI bus, device, and function number. > - * @reserved: Reserved (to naturally align struct pci_dev_ser). > + * @refcount: Reference count used by the PCI core to keep track of > whether it > + * is done using a device's struct pci_dev_ser. > */ > struct pci_dev_ser { > u32 domain; > u16 bdf; > - u16 reserved; > + u16 refcount; > } __packed; > > /** > diff --git a/include/linux/pci.h b/include/linux/pci.h > index d70080babd52..eb94cbd8ab9d 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -41,6 +41,7 @@ > #include > #include > #include > +#include > > #include > > @@ -594,6 +595,9 @@ struct pci_dev { > u8 tph_mode; /* TPH mode */ > u8 tph_req_type; /* TPH requester type > */ #endif > +#ifdef CONFIG_PCI_LIVEUPDATE > + struct pci_dev_ser *liveupdate_outgoing; /* State preserved > for next kernel */ +#endif > }; > > static inline struct pci_dev *pci_physfn(struct pci_dev *dev) > @@ -2880,6 +2884,14 @@ void pci_uevent_ers(struct pci_dev *pdev, enum > pci_ers_result err_type); #ifdef CONFIG_PCI_LIVEUPDATE > int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh); > void pci_liveupdate_unregister_flb(struct liveupdate_file_handler > *fh); + > +int pci_liveupdate_preserve(struct pci_dev *dev); > +void pci_liveupdate_unpreserve(struct pci_dev *dev); > + > +static inline struct pci_dev_ser *pci_liveupdate_outgoing(struct > pci_dev *dev) +{ > + return dev->liveupdate_outgoing; > +} > #else > static inline int pci_liveupdate_register_flb(struct > liveupdate_file_handler *fh) { > @@ -2889,6 +2901,20 @@ static inline int > pci_liveupdate_register_flb(struct liveupdate_file_handler *fh static > inline void pci_liveupdate_unregister_flb(struct > liveupdate_file_handler *fh) { } > + > +static inline int pci_liveupdate_preserve(struct pci_dev *dev) > +{ > + return -EOPNOTSUPP; > +} > + > +static inline void pci_liveupdate_unpreserve(struct pci_dev *dev) > +{ > +} > + > +static inline struct pci_dev_ser *pci_liveupdate_outgoing(struct > pci_dev *dev) +{ > + return NULL; > +} > #endif > > #endif /* LINUX_PCI_H */