This is to allow moving the mutex lock outside of pci_iov_add/rem_virtfn() for enabling/disabling SRIOV, while still making it possible to call the _locked version like it is the case for PPC's eeh_driver. CC: Alexander Duyck <alexander.h.duyck@xxxxxxxxx> Signed-off-by: Emil Tantilov <emil.s.tantilov@xxxxxxxxx> --- arch/powerpc/kernel/eeh_driver.c | 4 ++-- drivers/pci/iov.c | 31 ++++++++++++++++++++++++------- include/linux/pci.h | 4 ++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index d88573b..81aaea7 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -441,7 +441,7 @@ static void *eeh_add_virt_device(void *data, void *userdata) } #ifdef CONFIG_PPC_POWERNV - pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0); + pci_iov_add_virtfn_locked(edev->physfn, pdn->vf_index, 0); #endif return NULL; } @@ -499,7 +499,7 @@ static void *eeh_rmv_device(void *data, void *userdata) #ifdef CONFIG_PPC_POWERNV struct pci_dn *pdn = eeh_dev_to_pdn(edev); - pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0); + pci_iov_remove_virtfn_locked(edev->physfn, pdn->vf_index, 0); edev->pdev = NULL; /* diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4722782..fea322db 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -113,7 +113,7 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno) return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; } -int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) +static int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) { int i; int rc = -ENOMEM; @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) struct pci_sriov *iov = dev->sriov; struct pci_bus *bus; - mutex_lock(&iov->dev->sriov->lock); bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); if (!bus) goto failed; @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) __pci_reset_function(virtfn); pci_device_add(virtfn, virtfn->bus); - mutex_unlock(&iov->dev->sriov->lock); pci_bus_add_device(virtfn); sprintf(buf, "virtfn%u", id); @@ -191,11 +189,22 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) return rc; } -void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) +int pci_iov_add_virtfn_locked(struct pci_dev *dev, int id, int reset) +{ + struct pci_sriov *iov = dev->sriov; + int rc; + + mutex_lock(&iov->dev->sriov->lock); + rc = pci_iov_add_virtfn(dev, id, reset); + mutex_unlock(&iov->dev->sriov->lock); + + return rc; +} + +static void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) { char buf[VIRTFN_ID_LEN]; struct pci_dev *virtfn; - struct pci_sriov *iov = dev->sriov; virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), pci_iov_virtfn_bus(dev, id), @@ -218,16 +227,24 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) if (virtfn->dev.kobj.sd) sysfs_remove_link(&virtfn->dev.kobj, "physfn"); - mutex_lock(&iov->dev->sriov->lock); pci_stop_and_remove_bus_device(virtfn); virtfn_remove_bus(dev->bus, virtfn->bus); - mutex_unlock(&iov->dev->sriov->lock); /* balance pci_get_domain_bus_and_slot() */ pci_dev_put(virtfn); pci_dev_put(dev); } +void pci_iov_remove_virtfn_locked(struct pci_dev *dev, int id, int reset) +{ + struct pci_sriov *iov = dev->sriov; + + mutex_lock(&iov->dev->sriov->lock); + pci_iov_remove_virtfn(dev, id, reset); + mutex_unlock(&iov->dev->sriov->lock); +} + + int __weak pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) { return 0; diff --git a/include/linux/pci.h b/include/linux/pci.h index e2d1a12..4351ceb7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1872,8 +1872,8 @@ static inline void pci_mmcfg_late_init(void) { } int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); void pci_disable_sriov(struct pci_dev *dev); -int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset); -void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset); +int pci_iov_add_virtfn_locked(struct pci_dev *dev, int id, int reset); +void pci_iov_remove_virtfn_locked(struct pci_dev *dev, int id, int reset); int pci_num_vf(struct pci_dev *dev); int pci_vfs_assigned(struct pci_dev *dev); int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html