powerpc/powernv: Reserve additional space for IOV BAR, with m64_per_iov supported
M64 aperture size is limited on PHB3. When the IOV BAR is too big, this will exceed the limitation and failed to be assigned. Introduce a different mechanism based on the IOV BAR size: - if IOV BAR size is smaller than 64MB, expand to total_pe - if IOV BAR size is bigger than 64MB, roundup power2 [bhelgaas: make dev_printk() output more consistent, use PCI_SRIOV_NUM_BARS] Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
781a868f31
commit
5b88ec2284
@ -182,6 +182,8 @@ struct pci_dn {
|
||||
u16 vfs_expanded; /* number of VFs IOV BAR expanded */
|
||||
u16 num_vfs; /* number of VFs enabled*/
|
||||
int offset; /* PE# for the first VF PE */
|
||||
#define M64_PER_IOV 4
|
||||
int m64_per_iov;
|
||||
#define IODA_INVALID_M64 (-1)
|
||||
int m64_wins[PCI_SRIOV_NUM_BARS];
|
||||
#endif /* CONFIG_PCI_IOV */
|
||||
|
@ -2250,6 +2250,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
|
||||
int i;
|
||||
resource_size_t size;
|
||||
struct pci_dn *pdn;
|
||||
int mul, total_vfs;
|
||||
|
||||
if (!pdev->is_physfn || pdev->is_added)
|
||||
return;
|
||||
@ -2260,6 +2261,32 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
|
||||
pdn = pci_get_pdn(pdev);
|
||||
pdn->vfs_expanded = 0;
|
||||
|
||||
total_vfs = pci_sriov_get_totalvfs(pdev);
|
||||
pdn->m64_per_iov = 1;
|
||||
mul = phb->ioda.total_pe;
|
||||
|
||||
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
|
||||
res = &pdev->resource[i + PCI_IOV_RESOURCES];
|
||||
if (!res->flags || res->parent)
|
||||
continue;
|
||||
if (!pnv_pci_is_mem_pref_64(res->flags)) {
|
||||
dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n",
|
||||
i, res);
|
||||
continue;
|
||||
}
|
||||
|
||||
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
|
||||
|
||||
/* bigger than 64M */
|
||||
if (size > (1 << 26)) {
|
||||
dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
|
||||
i, res);
|
||||
pdn->m64_per_iov = M64_PER_IOV;
|
||||
mul = roundup_pow_of_two(total_vfs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
|
||||
res = &pdev->resource[i + PCI_IOV_RESOURCES];
|
||||
if (!res->flags || res->parent)
|
||||
@ -2272,12 +2299,12 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
|
||||
|
||||
dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
|
||||
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
|
||||
res->end = res->start + size * phb->ioda.total_pe - 1;
|
||||
res->end = res->start + size * mul - 1;
|
||||
dev_dbg(&pdev->dev, " %pR\n", res);
|
||||
dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
|
||||
i, res, phb->ioda.total_pe);
|
||||
i, res, mul);
|
||||
}
|
||||
pdn->vfs_expanded = phb->ioda.total_pe;
|
||||
pdn->vfs_expanded = mul;
|
||||
}
|
||||
#endif /* CONFIG_PCI_IOV */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user