[PATCH 1/2] PCI: introduce locked pci_add/remove_virtfn

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux