From: Keith Busch <kbusch@meta.com>
To: <linux-pci@vger.kernel.org>, <helgaas@kernel.org>
Cc: <alex@shazbot.org>, <lukas@wunner.de>, <dan.j.williams@intel.com>,
<guojinhui.liam@bytedance.com>, <ilpo.jarvinen@linux.intel.com>,
Keith Busch <kbusch@kernel.org>
Subject: [PATCHv2 4/4] pci: make reset_subordinate hotplug safe
Date: Fri, 30 Jan 2026 08:59:53 -0800 [thread overview]
Message-ID: <20260130165953.751063-5-kbusch@meta.com> (raw)
In-Reply-To: <20260130165953.751063-1-kbusch@meta.com>
From: Keith Busch <kbusch@kernel.org>
Use the slot reset method when resetting the bridge if the bus contains
hot plug slots. This fixes spurious hot plug events that are triggered
by the secondary bus reset that bypasses the slot's detection disabling.
Resetting a bridge's subordinate bus can be done like this:
# echo 1 > /sys/bus/pci/devices/0000:50:01.0/reset_subordinate
Prior to this patch, an example kernel message may show something like:
pcieport 0000:50:01.0: pciehp: Slot(40): Link Down
With this change, the pciehp driver ignores the link event during the
reset, so may show this message instead:
pcieport 0000:50:01.0: pciehp: Slot(40): Link Down/Up ignored
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/pci/pci-sysfs.c | 3 +-
drivers/pci/pci.c | 70 +++++++++++++++++++++++++++--------------
drivers/pci/pci.h | 2 +-
3 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c2df915ad2d29..0e1cef1c1c73b 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -553,7 +553,6 @@ static ssize_t reset_subordinate_store(struct device *dev,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
- struct pci_bus *bus = pdev->subordinate;
unsigned long val;
if (!capable(CAP_SYS_ADMIN))
@@ -563,7 +562,7 @@ static ssize_t reset_subordinate_store(struct device *dev,
return -EINVAL;
if (val) {
- int ret = __pci_reset_bus(bus);
+ int ret = pci_reset_bridge(pdev);
if (ret)
return ret;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 36427fbf7a747..12cf61a9bbeb1 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -50,6 +50,7 @@ EXPORT_SYMBOL(pci_pci_problems);
unsigned int pci_pm_d3hot_delay;
static void pci_pme_list_scan(struct work_struct *work);
+static int __pci_reset_bridge(struct pci_dev *bridge, bool save);
static LIST_HEAD(pci_pme_list);
static DEFINE_MUTEX(pci_pme_list_mutex);
@@ -5419,29 +5420,7 @@ static int pci_bus_reset(struct pci_bus *bus, bool probe)
*/
int pci_bus_error_reset(struct pci_dev *bridge)
{
- struct pci_bus *bus = bridge->subordinate;
- struct pci_slot *slot;
-
- if (!bus)
- return -ENOTTY;
-
- mutex_lock(&pci_slot_mutex);
- if (list_empty(&bus->slots))
- goto bus_reset;
-
- list_for_each_entry(slot, &bus->slots, list)
- if (pci_probe_reset_slot(slot))
- goto bus_reset;
-
- list_for_each_entry(slot, &bus->slots, list)
- if (pci_slot_reset(slot, PCI_RESET_DO_RESET))
- goto bus_reset;
-
- mutex_unlock(&pci_slot_mutex);
- return 0;
-bus_reset:
- mutex_unlock(&pci_slot_mutex);
- return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
+ return __pci_reset_bridge(bridge, false);
}
/**
@@ -5462,7 +5441,7 @@ EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
*
* Same as above except return -EAGAIN if the bus cannot be locked
*/
-int __pci_reset_bus(struct pci_bus *bus)
+static int __pci_reset_bus(struct pci_bus *bus)
{
int rc;
@@ -5482,6 +5461,49 @@ int __pci_reset_bus(struct pci_bus *bus)
return rc;
}
+static int __pci_reset_bridge(struct pci_dev *bridge, bool save)
+{
+ struct pci_bus *bus = bridge->subordinate;
+ struct pci_slot *slot;
+
+ if (!bus)
+ return -ENOTTY;
+
+ mutex_lock(&pci_slot_mutex);
+ if (list_empty(&bus->slots))
+ goto bus_reset;
+
+ list_for_each_entry(slot, &bus->slots, list)
+ if (pci_probe_reset_slot(slot))
+ goto bus_reset;
+
+ list_for_each_entry(slot, &bus->slots, list) {
+ int ret;
+
+ if (save)
+ ret = __pci_reset_slot(slot);
+ else
+ ret = pci_slot_reset(slot, PCI_RESET_DO_RESET);
+
+ if (ret)
+ goto bus_reset;
+ }
+
+ mutex_unlock(&pci_slot_mutex);
+ return 0;
+bus_reset:
+ mutex_unlock(&pci_slot_mutex);
+
+ if (save)
+ return __pci_reset_bus(bus);
+ return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
+}
+
+int pci_reset_bridge(struct pci_dev *bridge)
+{
+ return __pci_reset_bridge(bridge, true);
+}
+
/**
* pci_reset_bus - Try to reset a PCI bus
* @pdev: top level PCI device to reset via slot/bus
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0e67014aa0013..e537769cc3880 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -197,7 +197,7 @@ bool pci_reset_supported(struct pci_dev *dev);
void pci_init_reset_methods(struct pci_dev *dev);
int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
int pci_bus_error_reset(struct pci_dev *dev);
-int __pci_reset_bus(struct pci_bus *bus);
+int pci_reset_bridge(struct pci_dev *dev);
struct pci_cap_saved_data {
u16 cap_nr;
--
2.47.3
next prev parent reply other threads:[~2026-01-30 17:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-30 16:59 [PATCHv2 0/4] pci: slot handling fixes Keith Busch
2026-01-30 16:59 ` [PATCHv2 1/4] PCI: Fix incorrect unlocking in pci_slot_trylock() Keith Busch
2026-01-30 16:59 ` [PATCHv2 2/4] pci: fix slot reset device locking Keith Busch
2026-01-30 16:59 ` [PATCHv2 3/4] pci: remove slot specific lock/unlock and save/restore Keith Busch
2026-01-31 5:58 ` dan.j.williams
2026-02-04 21:33 ` Keith Busch
2026-02-02 20:27 ` Keith Busch
2026-01-30 16:59 ` Keith Busch [this message]
2026-01-31 6:42 ` [PATCHv2 4/4] pci: make reset_subordinate hotplug safe dan.j.williams
2026-02-04 22:31 ` Keith Busch
2026-01-31 0:18 ` [PATCHv2 0/4] pci: slot handling fixes Bjorn Helgaas
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=20260130165953.751063-5-kbusch@meta.com \
--to=kbusch@meta.com \
--cc=alex@shazbot.org \
--cc=dan.j.williams@intel.com \
--cc=guojinhui.liam@bytedance.com \
--cc=helgaas@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=kbusch@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
/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