From 582a686f52d2e002da64093fe4b9aa5befcaf4e4 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 18 Jan 2017 14:04:37 +0100 Subject: [PATCH 1/3] device: bus_type: Introduce num_vf callback This allows for bus types to implement their own method of retrieving the number of virtual functions a NIC on that type of bus supports. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- include/linux/device.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 491b4c0ca6333a..6d73b70a4a5d76 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -88,6 +88,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * * @suspend: Called when a device on this bus wants to go to sleep mode. * @resume: Called to bring a device on this bus out of sleep mode. + * @num_vf: Called to find out how many virtual functions a device on this + * bus supports. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU @@ -127,6 +129,8 @@ struct bus_type { int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); + int (*num_vf)(struct device *dev); + const struct dev_pm_ops *pm; const struct iommu_ops *iommu_ops; From 02e0bea6c83c657617195135667e6a3f50d3bfb3 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 18 Jan 2017 14:04:38 +0100 Subject: [PATCH 2/3] PCI: implement num_vf bus type callback Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/pci/pci-driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1ccce1cd6aca45..63d8e18fb6b143 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1432,6 +1432,11 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int pci_bus_num_vf(struct device *dev) +{ + return pci_num_vf(to_pci_dev(dev)); +} + struct bus_type pci_bus_type = { .name = "pci", .match = pci_bus_match, @@ -1443,6 +1448,7 @@ struct bus_type pci_bus_type = { .bus_groups = pci_bus_groups, .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, + .num_vf = pci_bus_num_vf, }; EXPORT_SYMBOL(pci_bus_type); From 9af15c38254d81c9991eba89335ca7c537d7f2c3 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 18 Jan 2017 14:04:39 +0100 Subject: [PATCH 3/3] device: Implement a bus agnostic dev_num_vf routine Now that pci_bus_type has num_vf callback set, dev_num_vf can be implemented in a bus type independent way and the check for whether a PCI device is being handled in rtnetlink can be dropped. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- include/linux/device.h | 7 +++++++ include/linux/pci.h | 2 -- net/core/rtnetlink.c | 3 +-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index 6d73b70a4a5d76..bd684fc8ec1d83 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1144,6 +1144,13 @@ extern int device_online(struct device *dev); extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); extern void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); +static inline int dev_num_vf(struct device *dev) +{ + if (dev->bus && dev->bus->num_vf) + return dev->bus->num_vf(dev); + return 0; +} + /* * Root device objects for grouping under /sys/devices */ diff --git a/include/linux/pci.h b/include/linux/pci.h index e2d1a124216a9c..adbc859fe7c4c0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -885,7 +885,6 @@ void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type); void pci_sort_breadthfirst(void); #define dev_is_pci(d) ((d)->bus == &pci_bus_type) #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false)) -#define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf(to_pci_dev(d)) : 0)) /* Generic PCI functions exported to card drivers */ @@ -1630,7 +1629,6 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } #define dev_is_pci(d) (false) #define dev_is_pf(d) (false) -#define dev_num_vf(d) (0) #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f538f764fca687..152744643074c8 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -837,8 +837,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, static inline int rtnl_vfinfo_size(const struct net_device *dev, u32 ext_filter_mask) { - if (dev->dev.parent && dev_is_pci(dev->dev.parent) && - (ext_filter_mask & RTEXT_FILTER_VF)) { + if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF)) { int num_vfs = dev_num_vf(dev->dev.parent); size_t size = nla_total_size(0); size += num_vfs *