aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorBodong Wang <bodong@mellanox.com>2017-04-13 01:51:40 +0300
committerBjorn Helgaas <bhelgaas@google.com>2017-04-20 08:53:51 -0500
commit0e7df22401a3dfd403b26dea62dd00e0598b538b (patch)
tree484063ef8f232bf8d51d998a1331513a9f2c8b5a /drivers/pci/pci-driver.c
parentPCI: Avoid FLR for Intel 82579 NICs (diff)
downloadlinux-dev-0e7df22401a3dfd403b26dea62dd00e0598b538b.tar.xz
linux-dev-0e7df22401a3dfd403b26dea62dd00e0598b538b.zip
PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding
Sometimes it is not desirable to bind SR-IOV VFs to drivers. This can save host side resource usage by VF instances that will be assigned to VMs. Add a new PCI sysfs interface "sriov_drivers_autoprobe" to control that from the PF. To modify it, echo 0/n/N (disable probe) or 1/y/Y (enable probe) to: /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe Note that this must be done before enabling VFs. The change will not take effect if VFs are already enabled. Simply, one can disable VFs by setting sriov_numvfs to 0, choose whether to probe or not, and then re-enable the VFs by restoring sriov_numvfs. [bhelgaas: changelog, ABI doc] Signed-off-by: Bodong Wang <bodong@mellanox.com> Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index afa72717a979..f99f7fe749b8 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -394,6 +394,18 @@ void __weak pcibios_free_irq(struct pci_dev *dev)
{
}
+#ifdef CONFIG_PCI_IOV
+static inline bool pci_device_can_probe(struct pci_dev *pdev)
+{
+ return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe);
+}
+#else
+static inline bool pci_device_can_probe(struct pci_dev *pdev)
+{
+ return true;
+}
+#endif
+
static int pci_device_probe(struct device *dev)
{
int error;
@@ -405,10 +417,12 @@ static int pci_device_probe(struct device *dev)
return error;
pci_dev_get(pci_dev);
- error = __pci_device_probe(drv, pci_dev);
- if (error) {
- pcibios_free_irq(pci_dev);
- pci_dev_put(pci_dev);
+ if (pci_device_can_probe(pci_dev)) {
+ error = __pci_device_probe(drv, pci_dev);
+ if (error) {
+ pcibios_free_irq(pci_dev);
+ pci_dev_put(pci_dev);
+ }
}
return error;