On Sat, Apr 20, 2013 at 9:31 PM, Jeff Kirsher <jeffrey.t.kirsher@xxxxxxxxx> wrote: > On Sat, 2013-04-20 at 02:49 -0700, Jeff Kirsher wrote: >> From: Alexander Duyck <alexander.h.duyck@xxxxxxxxx> >> >> This function is meant to add a helper function that will determine if a PF >> has any VFs that are currently assigned to a guest. We currently have been >> implementing this function per driver, and going forward I would like to avoid >> that by making this function generic and using this helper. >> >> Signed-off-by: Alexander Duyck <alexander.h.duyck@xxxxxxxxx> >> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@xxxxxxxxx> > > Adding linux-pci mailing list and Bjorn to the CC. > > Bjorn- David Miller needs a signoff by PCI maintainer. > >> --- >> drivers/pci/iov.c | 41 +++++++++++++++++++++++++++++++++++++++++ >> include/linux/pci.h | 5 +++++ >> 2 files changed, 46 insertions(+) >> >> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c >> index ee599f2..fd99720 100644 >> --- a/drivers/pci/iov.c >> +++ b/drivers/pci/iov.c >> @@ -729,6 +729,47 @@ int pci_num_vf(struct pci_dev *dev) >> EXPORT_SYMBOL_GPL(pci_num_vf); >> >> /** >> + * pci_vfs_assigned - returns number of VFs are assigned to a guest >> + * @dev: the PCI device >> + * >> + * Returns number of VFs belonging to this device that are assigned to a guest. >> + * If device is not a physical function returns -ENODEV. >> + */ >> +int pci_vfs_assigned(struct pci_dev *dev) I guess the idea here is to replace be_find_vfs(), igb_vfs_are_assigned(), ixgbe_vfs_are_assigned(), etc. It does seem good to reduce duplicated code. I'm trying to figure out why this is safe -- there's no explicit synchronization between the iteration through PCI devices looking for matching VFs and the device assignment/deassignment paths that set or clear PCI_DEV_FLAGS_ASSIGNED, so on the face of it, it looks like things could change between calling pci_vfs_assigned() and using the result to make a decision. Most of the calls would be in .remove() functions, so maybe there's some sort of synchronization in that path that makes this safe. Bjorn >> +{ >> + struct pci_dev *vfdev; >> + unsigned int vfs_assigned = 0; >> + unsigned short dev_id; >> + >> + /* only search if we are a PF */ >> + if (!dev->is_physfn) >> + return -ENODEV; >> + >> + /* >> + * determine the device ID for the VFs, the vendor ID will be the >> + * same as the PF so there is no need to check for that one >> + */ >> + pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); >> + >> + /* loop through all the VFs to see if we own any that are assigned */ >> + vfdev = pci_get_device(dev->vendor, dev_id, NULL); >> + while (vfdev) { >> + /* >> + * It is considered assigned if it is a virtual function with >> + * our dev as the physical function and the assigned bit is set >> + */ >> + if (vfdev->is_virtfn && (vfdev->physfn == dev) && >> + (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) >> + vfs_assigned++; >> + >> + vfdev = pci_get_device(dev->vendor, dev_id, vfdev); >> + } >> + >> + return vfs_assigned; >> +} >> +EXPORT_SYMBOL_GPL(pci_vfs_assigned); >> + >> +/** >> * pci_sriov_set_totalvfs -- reduce the TotalVFs available >> * @dev: the PCI PF device >> * @numvfs: number that should be used for TotalVFs supported >> diff --git a/include/linux/pci.h b/include/linux/pci.h >> index 2461033a..03b4d3c 100644 >> --- a/include/linux/pci.h >> +++ b/include/linux/pci.h >> @@ -1643,6 +1643,7 @@ 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_vfs_assigned(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 >> @@ -1661,6 +1662,10 @@ static inline int pci_num_vf(struct pci_dev *dev) >> { >> return 0; >> } >> +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; > > -- 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