diff options
author | Jon Derrick <jonathan.derrick@intel.com> | 2018-09-25 14:39:06 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2018-10-02 17:04:40 -0400 |
commit | de3ffa301142bf8802a7b0de17f9985acde5c223 (patch) | |
tree | fd1a9e0027b6ba22c3e7c211d93df7261ec1b071 | |
parent | 26ad34d510a87fc65caeb48fa85cce58d2477a88 (diff) |
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: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/setup-bus.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 79b1824e83b4..ed960436df5e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -811,6 +811,8 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, | |||
811 | static resource_size_t calculate_iosize(resource_size_t size, | 811 | static resource_size_t calculate_iosize(resource_size_t size, |
812 | resource_size_t min_size, | 812 | resource_size_t min_size, |
813 | resource_size_t size1, | 813 | resource_size_t size1, |
814 | resource_size_t add_size, | ||
815 | resource_size_t children_add_size, | ||
814 | resource_size_t old_size, | 816 | resource_size_t old_size, |
815 | resource_size_t align) | 817 | resource_size_t align) |
816 | { | 818 | { |
@@ -823,15 +825,18 @@ static resource_size_t calculate_iosize(resource_size_t size, | |||
823 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 825 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
824 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | 826 | size = (size & 0xff) + ((size & ~0xffUL) << 2); |
825 | #endif | 827 | #endif |
826 | size = ALIGN(size + size1, align); | 828 | size = size + size1; |
827 | if (size < old_size) | 829 | if (size < old_size) |
828 | size = old_size; | 830 | size = old_size; |
831 | |||
832 | size = ALIGN(max(size, add_size) + children_add_size, align); | ||
829 | return size; | 833 | return size; |
830 | } | 834 | } |
831 | 835 | ||
832 | static resource_size_t calculate_memsize(resource_size_t size, | 836 | static resource_size_t calculate_memsize(resource_size_t size, |
833 | resource_size_t min_size, | 837 | resource_size_t min_size, |
834 | resource_size_t size1, | 838 | resource_size_t add_size, |
839 | resource_size_t children_add_size, | ||
835 | resource_size_t old_size, | 840 | resource_size_t old_size, |
836 | resource_size_t align) | 841 | resource_size_t align) |
837 | { | 842 | { |
@@ -841,7 +846,8 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
841 | old_size = 0; | 846 | old_size = 0; |
842 | if (size < old_size) | 847 | if (size < old_size) |
843 | size = old_size; | 848 | size = old_size; |
844 | size = ALIGN(size + size1, align); | 849 | |
850 | size = ALIGN(max(size, add_size) + children_add_size, align); | ||
845 | return size; | 851 | return size; |
846 | } | 852 | } |
847 | 853 | ||
@@ -930,12 +936,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
930 | } | 936 | } |
931 | } | 937 | } |
932 | 938 | ||
933 | size0 = calculate_iosize(size, min_size, size1, | 939 | size0 = calculate_iosize(size, min_size, size1, 0, 0, |
934 | resource_size(b_res), min_align); | 940 | resource_size(b_res), min_align); |
935 | if (children_add_size > add_size) | 941 | size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 : |
936 | add_size = children_add_size; | 942 | calculate_iosize(size, min_size, size1, add_size, children_add_size, |
937 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | ||
938 | calculate_iosize(size, min_size, add_size + size1, | ||
939 | resource_size(b_res), min_align); | 943 | resource_size(b_res), min_align); |
940 | if (!size0 && !size1) { | 944 | if (!size0 && !size1) { |
941 | if (b_res->start || b_res->end) | 945 | if (b_res->start || b_res->end) |
@@ -1079,12 +1083,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
1079 | 1083 | ||
1080 | min_align = calculate_mem_align(aligns, max_order); | 1084 | min_align = calculate_mem_align(aligns, max_order); |
1081 | min_align = max(min_align, window_alignment(bus, b_res->flags)); | 1085 | min_align = max(min_align, window_alignment(bus, b_res->flags)); |
1082 | size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); | 1086 | size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align); |
1083 | add_align = max(min_align, add_align); | 1087 | add_align = max(min_align, add_align); |
1084 | if (children_add_size > add_size) | 1088 | size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 : |
1085 | add_size = children_add_size; | 1089 | calculate_memsize(size, min_size, add_size, children_add_size, |
1086 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | ||
1087 | calculate_memsize(size, min_size, add_size, | ||
1088 | resource_size(b_res), add_align); | 1090 | resource_size(b_res), add_align); |
1089 | if (!size0 && !size1) { | 1091 | if (!size0 && !size1) { |
1090 | if (b_res->start || b_res->end) | 1092 | if (b_res->start || b_res->end) |