@@ -574,6 +574,22 @@ void pci_iov_release(struct pci_dev *dev)
sriov_release(dev);
}
+/**
+ * pci_sriov_drv_cleanup - clean up SR-IOV state after PF driver is detached
+ * @dev: the PCI device
+ */
+void pci_sriov_drv_cleanup(struct pci_dev *dev)
+{
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!dev->is_physfn)
+ return;
+ iov->driver_max_VFs = iov->total_VFs;
+ if (iov->num_VFs)
+ dev_warn(&dev->dev,
+ "driver left SR-IOV enabled after remove\n");
+}
+
/**
* pci_iov_update_resource - update a VF BAR
* @dev: the PCI device
@@ -443,6 +443,7 @@ static int pci_device_remove(struct device *dev)
}
pcibios_free_irq(pci_dev);
pci_dev->driver = NULL;
+ pci_sriov_drv_cleanup(pci_dev);
}
/* Undo the runtime PM settings in local_pci_probe() */
@@ -311,6 +311,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
#ifdef CONFIG_PCI_IOV
int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev);
+void pci_sriov_drv_cleanup(struct pci_dev *dev);
void pci_iov_update_resource(struct pci_dev *dev, int resno);
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
void pci_restore_iov_state(struct pci_dev *dev);
@@ -323,6 +324,9 @@ static inline int pci_iov_init(struct pci_dev *dev)
}
static inline void pci_iov_release(struct pci_dev *dev)
+{
+}
+static inline void pci_sriov_drv_cleanup(struct pci_dev *dev)
{
}
static inline void pci_restore_iov_state(struct pci_dev *dev)
Bjorn points out that currently core and most of the drivers don't clean up dev->sriov->driver_max_VFs settings on .remove(). This means that if a different driver is bound afterwards it will inherit the old setting: - load PF driver 1 - driver calls pci_sriov_set_totalvfs() to reduce driver_max_VFs - unload PF driver 1 - load PF driver 2 Reset driver_max_VFs back to total_VFs after device remove. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> --- I gave into the temptation and also added a warning about SR-IOV being on after remove :) Please let me know if this is anywhere close to what you had in mind! drivers/pci/iov.c | 16 ++++++++++++++++ drivers/pci/pci-driver.c | 1 + drivers/pci/pci.h | 4 ++++ 3 files changed, 21 insertions(+)