All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: allow drivers to limit the number of VFs to 0
@ 2018-04-02 22:46 Jakub Kicinski
  2018-05-24 23:57 ` Bjorn Helgaas
  0 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2018-04-02 22:46 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, netdev, Sathya Perla, Felix Manlunas, alexander.duyck,
	john.fastabend, Jacob Keller, Donald Dutile, oss-drivers,
	Christoph Hellwig, Jakub Kicinski

Some user space depends on enabling sriov_totalvfs number of VFs
to not fail, e.g.:

$ cat .../sriov_totalvfs > .../sriov_numvfs

For devices which VF support depends on loaded FW we have the
pci_sriov_{g,s}et_totalvfs() API.  However, this API uses 0 as
a special "unset" value, meaning drivers can't limit sriov_totalvfs
to 0.  Remove the special values completely and simply initialize
driver_max_VFs to total_VFs.  Then always use driver_max_VFs.
Add a helper for drivers to reset the VF limit back to total.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_main.c |  6 +++---
 drivers/pci/iov.c                             | 27 +++++++++++++++++++++------
 include/linux/pci.h                           |  2 ++
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index c4b1f344b4da..a76d177e40dd 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -123,7 +123,7 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
 		return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
 
 	pf->limit_vfs = ~0;
-	pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */
+	pci_sriov_reset_totalvfs(pf->pdev);
 	/* Allow any setting for backwards compatibility if symbol not found */
 	if (err == -ENOENT)
 		return 0;
@@ -537,7 +537,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
 err_net_remove:
 	nfp_net_pci_remove(pf);
 err_sriov_unlimit:
-	pci_sriov_set_totalvfs(pf->pdev, 0);
+	pci_sriov_reset_totalvfs(pf->pdev);
 err_fw_unload:
 	kfree(pf->rtbl);
 	nfp_mip_close(pf->mip);
@@ -570,7 +570,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
 	nfp_hwmon_unregister(pf);
 
 	nfp_pcie_sriov_disable(pdev);
-	pci_sriov_set_totalvfs(pf->pdev, 0);
+	pci_sriov_reset_totalvfs(pf->pdev);
 
 	nfp_net_pci_remove(pf);
 
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 677924ae0350..c63ea870d8be 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -443,6 +443,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
 	iov->nres = nres;
 	iov->ctrl = ctrl;
 	iov->total_VFs = total;
+	iov->driver_max_VFs = total;
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &iov->vf_device);
 	iov->pgsz = pgsz;
 	iov->self = dev;
@@ -788,12 +789,29 @@ int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
 }
 EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
 
+/**
+ * pci_sriov_reset_totalvfs -- return the TotalVFs value to the default
+ * @dev: the PCI PF device
+ *
+ * Should be called from PF driver's remove routine with
+ * device's mutex held.
+ */
+void pci_sriov_reset_totalvfs(struct pci_dev *dev)
+{
+	/* Shouldn't change if VFs already enabled */
+	if (!dev->is_physfn || dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE)
+		return;
+
+	dev->sriov->driver_max_VFs = dev->sriov->total_VFs;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_reset_totalvfs);
+
 /**
  * pci_sriov_get_totalvfs -- get total VFs supported on this device
  * @dev: the PCI PF device
  *
- * For a PCIe device with SRIOV support, return the PCIe
- * SRIOV capability value of TotalVFs or the value of driver_max_VFs
+ * For a PCIe device with SRIOV support, return the value of driver_max_VFs
+ * which can be equal to the PCIe SRIOV capability value of TotalVFs or lower
  * if the driver reduced it.  Otherwise 0.
  */
 int pci_sriov_get_totalvfs(struct pci_dev *dev)
@@ -801,9 +819,6 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev)
 	if (!dev->is_physfn)
 		return 0;
 
-	if (dev->sriov->driver_max_VFs)
-		return dev->sriov->driver_max_VFs;
-
-	return dev->sriov->total_VFs;
+	return dev->sriov->driver_max_VFs;
 }
 EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 024a1beda008..95fde8850393 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1952,6 +1952,7 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
 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);
+void pci_sriov_reset_totalvfs(struct pci_dev *dev);
 int pci_sriov_get_totalvfs(struct pci_dev *dev);
 resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno);
 void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe);
@@ -1978,6 +1979,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev)
 { return 0; }
 static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
 { return 0; }
+static inline void pci_sriov_reset_totalvfs(struct pci_dev *dev) { }
 static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
 { return 0; }
 static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 23+ messages in thread
* [PATCH] PCI: allow drivers to limit the number of VFs to 0
@ 2018-03-29 18:22 Jakub Kicinski
  2018-03-30 11:49 ` Christoph Hellwig
  0 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2018-03-29 18:22 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-pci, netdev, Sathya Perla, Felix Manlunas, alexander.duyck,
	john.fastabend, Jacob Keller, Donald Dutile, oss-drivers,
	Jakub Kicinski

Some user space depends on driver allowing sriov_totalvfs to be
enabled.  For devices which VF support depends on loaded FW we
have the pci_sriov_{g,s}et_totalvfs() API.  However, this API
uses 0 as a special "unset" value, meaning drivers can't limit
sriov_totalvfs to 0.  Change the special value to be U16_MAX.
Use simple min() to determine actual totalvfs.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_main.c | 6 +++---
 drivers/pci/iov.c                             | 6 ++----
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index c4b1f344b4da..dcd6e208a155 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -123,7 +123,7 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
 		return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
 
 	pf->limit_vfs = ~0;
-	pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */
+	pci_sriov_set_totalvfs(pf->pdev, ~0);
 	/* Allow any setting for backwards compatibility if symbol not found */
 	if (err == -ENOENT)
 		return 0;
@@ -537,7 +537,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
 err_net_remove:
 	nfp_net_pci_remove(pf);
 err_sriov_unlimit:
-	pci_sriov_set_totalvfs(pf->pdev, 0);
+	pci_sriov_set_totalvfs(pf->pdev, ~0);
 err_fw_unload:
 	kfree(pf->rtbl);
 	nfp_mip_close(pf->mip);
@@ -570,7 +570,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
 	nfp_hwmon_unregister(pf);
 
 	nfp_pcie_sriov_disable(pdev);
-	pci_sriov_set_totalvfs(pf->pdev, 0);
+	pci_sriov_set_totalvfs(pf->pdev, ~0);
 
 	nfp_net_pci_remove(pf);
 
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 677924ae0350..aa3dfe3ecd68 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -446,6 +446,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
 	pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &iov->vf_device);
 	iov->pgsz = pgsz;
 	iov->self = dev;
+	iov->driver_max_VFs = U16_MAX;
 	iov->drivers_autoprobe = true;
 	pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
 	pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
@@ -801,9 +802,6 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev)
 	if (!dev->is_physfn)
 		return 0;
 
-	if (dev->sriov->driver_max_VFs)
-		return dev->sriov->driver_max_VFs;
-
-	return dev->sriov->total_VFs;
+	return min(dev->sriov->total_VFs, dev->sriov->driver_max_VFs);
 }
 EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2018-06-20  2:56 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-02 22:46 [PATCH] PCI: allow drivers to limit the number of VFs to 0 Jakub Kicinski
2018-05-24 23:57 ` Bjorn Helgaas
2018-05-25  1:20   ` Jakub Kicinski
2018-05-25 14:02     ` Bjorn Helgaas
2018-05-25 17:01       ` Bjorn Helgaas
2018-05-25 17:01         ` [Intel-wired-lan] " Bjorn Helgaas
2018-05-25 17:46         ` Keller, Jacob E
2018-05-25 17:46           ` [Intel-wired-lan] " Keller, Jacob E
2018-05-25 17:46           ` Keller, Jacob E
2018-05-25 19:27       ` Don Dutile
2018-05-25 20:46         ` Bjorn Helgaas
2018-05-29 14:29           ` Don Dutile
2018-05-25 21:05       ` Jakub Kicinski
2018-05-25 21:45         ` Bjorn Helgaas
2018-05-26  3:00           ` [PATCH] PCI: reset driver SR-IOV state after remove Jakub Kicinski
2018-05-29 14:34         ` [PATCH] PCI: allow drivers to limit the number of VFs to 0 Don Dutile
2018-06-19 21:37       ` Bjorn Helgaas
2018-06-20  2:56         ` Jakub Kicinski
  -- strict thread matches above, loose matches on Subject: below --
2018-03-29 18:22 Jakub Kicinski
2018-03-30 11:49 ` Christoph Hellwig
2018-03-30 16:54   ` Alexander Duyck
2018-04-02 21:18     ` Jakub Kicinski
2018-04-02 21:17   ` Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.