Merge branch 'pci/virtualization'

- Add rescan/remove locking when enabling/disabling SR-IOV, which solves
  list corruption on s390, where disabling SR-IOV also generates hotplug
  events (Niklas Schnelle)

- Add lockdep assertion in pci_stop_and_remove_bus_device() to catch
  device removal without appropriate locking (Niklas Schnelle)

* pci/virtualization:
  PCI: Add lockdep assertion in pci_stop_and_remove_bus_device()
  PCI/IOV: Add PCI rescan-remove locking when enabling/disabling SR-IOV
This commit is contained in:
Bjorn Helgaas 2025-10-03 12:13:12 -05:00
commit 3d56c86318
4 changed files with 9 additions and 1 deletions

View File

@ -629,15 +629,18 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs)
if (dev->no_vf_scan)
return 0;
pci_lock_rescan_remove();
for (i = 0; i < num_vfs; i++) {
rc = pci_iov_add_virtfn(dev, i);
if (rc)
goto failed;
}
pci_unlock_rescan_remove();
return 0;
failed:
while (i--)
pci_iov_remove_virtfn(dev, i);
pci_unlock_rescan_remove();
return rc;
}
@ -762,8 +765,10 @@ static void sriov_del_vfs(struct pci_dev *dev)
struct pci_sriov *iov = dev->sriov;
int i;
pci_lock_rescan_remove();
for (i = 0; i < iov->num_VFs; i++)
pci_iov_remove_virtfn(dev, i);
pci_unlock_rescan_remove();
}
static void sriov_disable(struct pci_dev *dev)

View File

@ -89,6 +89,8 @@ struct pcie_tlp_log;
extern const unsigned char pcie_link_speed[];
extern bool pci_early_dump;
extern struct mutex pci_rescan_remove_lock;
bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
bool pcie_cap_has_lnkctl2(const struct pci_dev *dev);
bool pcie_cap_has_rtctl(const struct pci_dev *dev);

View File

@ -3507,7 +3507,7 @@ EXPORT_SYMBOL_GPL(pci_rescan_bus);
* pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal
* routines should always be executed under this mutex.
*/
static DEFINE_MUTEX(pci_rescan_remove_lock);
DEFINE_MUTEX(pci_rescan_remove_lock);
void pci_lock_rescan_remove(void)
{

View File

@ -140,6 +140,7 @@ static void pci_remove_bus_device(struct pci_dev *dev)
*/
void pci_stop_and_remove_bus_device(struct pci_dev *dev)
{
lockdep_assert_held(&pci_rescan_remove_lock);
pci_stop_bus_device(dev);
pci_remove_bus_device(dev);
}