aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorWei Yang <weiyang@linux.vnet.ibm.com>2015-03-25 04:23:47 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-30 22:02:36 -0400
commit4449f079722c86d2f6925da039835acdd8e973a8 (patch)
tree52eafc1494e73fb9a1b630a50cd8b15f339cac78 /drivers/pci
parentf59dca27d20c73500c4a88ab9a077e40669755db (diff)
PCI: Calculate maximum number of buses required for VFs
An SR-IOV device can change its First VF Offset and VF Stride based on the values of ARI Capable Hierarchy and NumVFs. The number of buses required for all VFs is determined by NumVFs, First VF Offset, and VF Stride (see SR-IOV spec r1.1, sec 2.1.2). Previously pci_iov_bus_range() computed how many buses would be required by TotalVFs, but this was based on a single NumVFs value and may not have been the maximum for all NumVFs configurations. Iterate over all valid NumVFs and calculate the maximum number of bus numbers that could ever be required for VFs of this device. [bhelgaas: changelog, compute busnr of NumVFs, not TotalVFs, remove kerenl-doc comment marker] Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/iov.c31
-rw-r--r--drivers/pci/pci.h1
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index a8752c2c2b53..2ae921f84bd3 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -46,6 +46,30 @@ static inline void pci_iov_set_numvfs(struct pci_dev *dev, int nr_virtfn)
46 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride); 46 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride);
47} 47}
48 48
49/*
50 * The PF consumes one bus number. NumVFs, First VF Offset, and VF Stride
51 * determine how many additional bus numbers will be consumed by VFs.
52 *
53 * Iterate over all valid NumVFs and calculate the maximum number of bus
54 * numbers that could ever be required.
55 */
56static inline u8 virtfn_max_buses(struct pci_dev *dev)
57{
58 struct pci_sriov *iov = dev->sriov;
59 int nr_virtfn;
60 u8 max = 0;
61 u8 busnr;
62
63 for (nr_virtfn = 1; nr_virtfn <= iov->total_VFs; nr_virtfn++) {
64 pci_iov_set_numvfs(dev, nr_virtfn);
65 busnr = virtfn_bus(dev, nr_virtfn - 1);
66 if (busnr > max)
67 max = busnr;
68 }
69
70 return max;
71}
72
49static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) 73static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
50{ 74{
51 struct pci_bus *child; 75 struct pci_bus *child;
@@ -427,6 +451,7 @@ found:
427 451
428 dev->sriov = iov; 452 dev->sriov = iov;
429 dev->is_physfn = 1; 453 dev->is_physfn = 1;
454 iov->max_VF_buses = virtfn_max_buses(dev);
430 455
431 return 0; 456 return 0;
432 457
@@ -556,15 +581,13 @@ void pci_restore_iov_state(struct pci_dev *dev)
556int pci_iov_bus_range(struct pci_bus *bus) 581int pci_iov_bus_range(struct pci_bus *bus)
557{ 582{
558 int max = 0; 583 int max = 0;
559 u8 busnr;
560 struct pci_dev *dev; 584 struct pci_dev *dev;
561 585
562 list_for_each_entry(dev, &bus->devices, bus_list) { 586 list_for_each_entry(dev, &bus->devices, bus_list) {
563 if (!dev->is_physfn) 587 if (!dev->is_physfn)
564 continue; 588 continue;
565 busnr = virtfn_bus(dev, dev->sriov->total_VFs - 1); 589 if (dev->sriov->max_VF_buses > max)
566 if (busnr > max) 590 max = dev->sriov->max_VF_buses;
567 max = busnr;
568 } 591 }
569 592
570 return max ? max - bus->number : 0; 593 return max ? max - bus->number : 0;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 57329645dd01..bae593c04541 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -243,6 +243,7 @@ struct pci_sriov {
243 u16 stride; /* following VF stride */ 243 u16 stride; /* following VF stride */
244 u32 pgsz; /* page size for BAR alignment */ 244 u32 pgsz; /* page size for BAR alignment */
245 u8 link; /* Function Dependency Link */ 245 u8 link; /* Function Dependency Link */
246 u8 max_VF_buses; /* max buses consumed by VFs */
246 u16 driver_max_VFs; /* max num VFs driver supports */ 247 u16 driver_max_VFs; /* max num VFs driver supports */
247 struct pci_dev *dev; /* lowest numbered PF */ 248 struct pci_dev *dev; /* lowest numbered PF */
248 struct pci_dev *self; /* this PF */ 249 struct pci_dev *self; /* this PF */