PCI : Calculate right add_size
During debug of one SRIOV enabled hotplug device, we found found that add_size is not passed properly. The device has devices under two level bridges: +-[0000:80]-+-00.0-[81-8f]-- | +-01.0-[90-9f]-- | +-02.0-[a0-af]----00.0-[a1-a3]--+-02.0-[a2]--+-00.0 Oracle Corporation Device | | \-03.0-[a3]--+-00.0 Oracle Corporation Device Which means later the parent bridge will not try to add a big enough range: [ 557.455077] pci 0000:a0:00.0: BAR 14: assigned [mem 0xf9000000-0xf93fffff] [ 557.461974] pci 0000:a0:00.0: BAR 15: assigned [mem 0xf6000000-0xf61fffff pref] [ 557.469340] pci 0000:a1:02.0: BAR 14: assigned [mem 0xf9000000-0xf91fffff] [ 557.476231] pci 0000:a1:02.0: BAR 15: assigned [mem 0xf6000000-0xf60fffff pref] [ 557.483582] pci 0000:a1:03.0: BAR 14: assigned [mem 0xf9200000-0xf93fffff] [ 557.490468] pci 0000:a1:03.0: BAR 15: assigned [mem 0xf6100000-0xf61fffff pref] [ 557.497833] pci 0000:a1:03.0: BAR 14: can't assign mem (size 0x200000) [ 557.504378] pci 0000:a1:03.0: failed to add optional resources res=[mem 0xf9200000-0xf93fffff] [ 557.513026] pci 0000:a1:02.0: BAR 14: can't assign mem (size 0x200000) [ 557.519578] pci 0000:a1:02.0: failed to add optional resources res=[mem 0xf9000000-0xf91fffff] It turns out we did not calculate size1 properly. static resource_size_t calculate_memsize(resource_size_t size, resource_size_t min_size, resource_size_t size1, resource_size_t old_size, resource_size_t align) { if (size < min_size) size = min_size; if (old_size == 1 ) old_size = 0; if (size < old_size) size = old_size; size = ALIGN(size + size1, align); return size; } We should not pass add_size with min_size in calculate_memsize since that will make add_size not contribute final add_size. So just pass add_size with size1 to calculate_memsize(). With this change, we should have chance to remove extra addon in pci_reassign_resource. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
0dea210b17
commit
a4ac9fea01
@ -612,7 +612,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
|
|||||||
if (children_add_size > add_size)
|
if (children_add_size > add_size)
|
||||||
add_size = children_add_size;
|
add_size = children_add_size;
|
||||||
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
|
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
|
||||||
calculate_iosize(size, min_size+add_size, size1,
|
calculate_iosize(size, min_size, add_size + size1,
|
||||||
resource_size(b_res), 4096);
|
resource_size(b_res), 4096);
|
||||||
if (!size0 && !size1) {
|
if (!size0 && !size1) {
|
||||||
if (b_res->start || b_res->end)
|
if (b_res->start || b_res->end)
|
||||||
@ -726,7 +726,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
|||||||
if (children_add_size > add_size)
|
if (children_add_size > add_size)
|
||||||
add_size = children_add_size;
|
add_size = children_add_size;
|
||||||
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
|
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
|
||||||
calculate_memsize(size, min_size+add_size, 0,
|
calculate_memsize(size, min_size, add_size,
|
||||||
resource_size(b_res), min_align);
|
resource_size(b_res), min_align);
|
||||||
if (!size0 && !size1) {
|
if (!size0 && !size1) {
|
||||||
if (b_res->start || b_res->end)
|
if (b_res->start || b_res->end)
|
||||||
|
@ -255,11 +255,12 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_size = resource_size(res) + addsize + min_align;
|
/* already aligned with min_align */
|
||||||
|
new_size = resource_size(res) + addsize;
|
||||||
ret = _pci_assign_resource(dev, resno, new_size, min_align);
|
ret = _pci_assign_resource(dev, resno, new_size, min_align);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
res->flags &= ~IORESOURCE_STARTALIGN;
|
res->flags &= ~IORESOURCE_STARTALIGN;
|
||||||
dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
|
dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
|
||||||
if (resno < PCI_BRIDGE_RESOURCES)
|
if (resno < PCI_BRIDGE_RESOURCES)
|
||||||
pci_update_resource(dev, resno);
|
pci_update_resource(dev, resno);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user