Skip to content

Commit

Permalink
PCI: Provide method to reduce the number of total VFs supported
Browse files Browse the repository at this point in the history
Some implementations of SRIOV provide a capability structure
value of TotalVFs that is greater than what the software can support.
Provide a method to reduce the capability structure reported value
to the value the driver can support.
This ensures sysfs reports the current capability of the system,
hardware and software.
Example for its use: igb & ixgbe -- report 8 & 64 as TotalVFs,
but drivers only support 7 & 63 maximum.

Signed-off-by: Donald Dutile <ddutile@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Donald Dutile authored and Bjorn Helgaas committed Nov 10, 2012
1 parent 1789382 commit bff7315
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
47 changes: 47 additions & 0 deletions drivers/pci/iov.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,3 +735,50 @@ int pci_num_vf(struct pci_dev *dev)
return dev->sriov->nr_virtfn;
}
EXPORT_SYMBOL_GPL(pci_num_vf);

/**
* pci_sriov_set_totalvfs -- reduce the TotalVFs available
* @dev: the PCI PF device
* numvfs: number that should be used for TotalVFs supported
*
* Should be called from PF driver's probe routine with
* device's mutex held.
*
* Returns 0 if PF is an SRIOV-capable device and
* value of numvfs valid. If not a PF with VFS, return -EINVAL;
* if VFs already enabled, return -EBUSY.
*/
int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{
if (!dev || !dev->is_physfn || (numvfs > dev->sriov->total))
return -EINVAL;

/* Shouldn't change if VFs already enabled */
if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE)
return -EBUSY;
else
dev->sriov->drvttl = numvfs;

return 0;
}
EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);

/**
* pci_sriov_get_totalvfs -- get total VFs supported on this devic3
* @dev: the PCI PF device
*
* For a PCIe device with SRIOV support, return the PCIe
* SRIOV capability value of TotalVFs or the value of drvttl
* if the driver reduced it. Otherwise, -EINVAL.
*/
int pci_sriov_get_totalvfs(struct pci_dev *dev)
{
if (!dev || !dev->is_physfn)
return -EINVAL;

if (dev->sriov->drvttl)
return dev->sriov->drvttl;
else
return dev->sriov->total;
}
EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
4 changes: 2 additions & 2 deletions drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ static ssize_t sriov_totalvfs_show(struct device *dev,
{
struct pci_dev *pdev = to_pci_dev(dev);

return sprintf(buf, "%u\n", pdev->sriov->total);
return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev));
}


Expand Down Expand Up @@ -452,7 +452,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
}

/* if enabling vf's ... */
total = pdev->sriov->total;
total = pci_sriov_get_totalvfs(pdev);
/* Requested VFs to enable < totalvfs and none enabled already */
if ((num_vfs > 0) && (num_vfs <= total)) {
if (pdev->sriov->nr_virtfn == 0) {
Expand Down
1 change: 1 addition & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ struct pci_sriov {
u16 stride; /* following VF stride */
u32 pgsz; /* page size for BAR alignment */
u8 link; /* Function Dependency Link */
u16 drvttl; /* max num VFs driver supports */
struct pci_dev *dev; /* lowest numbered PF */
struct pci_dev *self; /* this PF */
struct mutex lock; /* lock for VF bus */
Expand Down
10 changes: 10 additions & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,8 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
extern void pci_disable_sriov(struct pci_dev *dev);
extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
extern int pci_num_vf(struct pci_dev *dev);
extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
#else
static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
{
Expand All @@ -1627,6 +1629,14 @@ static inline int pci_num_vf(struct pci_dev *dev)
{
return 0;
}
static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{
return 0;
}
static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
{
return 0;
}
#endif

#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
Expand Down

0 comments on commit bff7315

Please sign in to comment.