Commit de3ffa30 authored by Jon Derrick's avatar Jon Derrick Committed by Bjorn Helgaas

PCI: Equalize hotplug memory and io for occupied and empty slots

Currently, a hotplug bridge will be given hpmemsize additional memory
and hpiosize additional io if available, in order to satisfy any future
hotplug allocation requirements.

These calculations don't consider the current memory/io size of the
hotplug bridge/slot, so hotplug bridges/slots which have downstream
devices will be allocated their current allocation in addition to the
hpmemsize value.

This makes for possibly undesirable results with a mix of unoccupied and
occupied slots (ex, with hpmemsize=2M):

  02:03.0 PCI bridge: <-- Occupied
	  Memory behind bridge: d6200000-d64fffff [size=3M]
  02:04.0 PCI bridge: <-- Unoccupied
	  Memory behind bridge: d6500000-d66fffff [size=2M]

This change considers the current allocation size when using the
hpmemsize/hpiosize parameters to make the reservations predictable for
the mix of unoccupied and occupied slots:

  02:03.0 PCI bridge: <-- Occupied
	  Memory behind bridge: d6200000-d63fffff [size=2M]
  02:04.0 PCI bridge: <-- Unoccupied
	  Memory behind bridge: d6400000-d65fffff [size=2M]
Signed-off-by: default avatarJon Derrick <jonathan.derrick@intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 26ad34d5
...@@ -811,6 +811,8 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, ...@@ -811,6 +811,8 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus,
static resource_size_t calculate_iosize(resource_size_t size, static resource_size_t calculate_iosize(resource_size_t size,
resource_size_t min_size, resource_size_t min_size,
resource_size_t size1, resource_size_t size1,
resource_size_t add_size,
resource_size_t children_add_size,
resource_size_t old_size, resource_size_t old_size,
resource_size_t align) resource_size_t align)
{ {
...@@ -823,15 +825,18 @@ static resource_size_t calculate_iosize(resource_size_t size, ...@@ -823,15 +825,18 @@ static resource_size_t calculate_iosize(resource_size_t size,
#if defined(CONFIG_ISA) || defined(CONFIG_EISA) #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
size = (size & 0xff) + ((size & ~0xffUL) << 2); size = (size & 0xff) + ((size & ~0xffUL) << 2);
#endif #endif
size = ALIGN(size + size1, align); size = size + size1;
if (size < old_size) if (size < old_size)
size = old_size; size = old_size;
size = ALIGN(max(size, add_size) + children_add_size, align);
return size; return size;
} }
static resource_size_t calculate_memsize(resource_size_t size, static resource_size_t calculate_memsize(resource_size_t size,
resource_size_t min_size, resource_size_t min_size,
resource_size_t size1, resource_size_t add_size,
resource_size_t children_add_size,
resource_size_t old_size, resource_size_t old_size,
resource_size_t align) resource_size_t align)
{ {
...@@ -841,7 +846,8 @@ static resource_size_t calculate_memsize(resource_size_t size, ...@@ -841,7 +846,8 @@ static resource_size_t calculate_memsize(resource_size_t size,
old_size = 0; old_size = 0;
if (size < old_size) if (size < old_size)
size = old_size; size = old_size;
size = ALIGN(size + size1, align);
size = ALIGN(max(size, add_size) + children_add_size, align);
return size; return size;
} }
...@@ -930,12 +936,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, ...@@ -930,12 +936,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
} }
} }
size0 = calculate_iosize(size, min_size, size1, size0 = calculate_iosize(size, min_size, size1, 0, 0,
resource_size(b_res), min_align); resource_size(b_res), min_align);
if (children_add_size > add_size) size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 :
add_size = children_add_size; calculate_iosize(size, min_size, size1, add_size, children_add_size,
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
calculate_iosize(size, min_size, add_size + size1,
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)
...@@ -1079,12 +1083,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, ...@@ -1079,12 +1083,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
min_align = calculate_mem_align(aligns, max_order); min_align = calculate_mem_align(aligns, max_order);
min_align = max(min_align, window_alignment(bus, b_res->flags)); min_align = max(min_align, window_alignment(bus, b_res->flags));
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align);
add_align = max(min_align, add_align); add_align = max(min_align, add_align);
if (children_add_size > add_size) size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 :
add_size = children_add_size; calculate_memsize(size, min_size, add_size, children_add_size,
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
calculate_memsize(size, min_size, add_size,
resource_size(b_res), add_align); resource_size(b_res), add_align);
if (!size0 && !size1) { if (!size0 && !size1) {
if (b_res->start || b_res->end) if (b_res->start || b_res->end)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment