Skip to content

Commit be76891

Browse files
Yinghai Lujbarnes993
authored andcommitted
PCI: honor child buses add_size in hot plug configuration
git commit c8adf9a "PCI: pre-allocate additional resources to devices only after successful allocation of essential resources." fails to take into consideration the optional-resources needed by children devices while calculating the optional-resource needed by the bridge. This can be a problem on some setup. For example, if a hotplug bridge has 8 children hotplug bridges, the bridge should have enough resources to accomodate the hotplug requirements for each of its children hotplug bridges. Currently this is not the case. This patch fixes the problem. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Reviewed-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
1 parent b03e749 commit be76891

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

drivers/pci/setup-bus.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,20 @@ static resource_size_t calculate_memsize(resource_size_t size,
540540
return size;
541541
}
542542

543+
static resource_size_t get_res_add_size(struct resource_list_x *add_head,
544+
struct resource *res)
545+
{
546+
struct resource_list_x *list;
547+
548+
/* check if it is in add_head list */
549+
for (list = add_head->next; list && list->res != res;
550+
list = list->next);
551+
if (list)
552+
return list->add_size;
553+
554+
return 0;
555+
}
556+
543557
/**
544558
* pbus_size_io() - size the io window of a given bus
545559
*
@@ -559,6 +573,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
559573
struct pci_dev *dev;
560574
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
561575
unsigned long size = 0, size0 = 0, size1 = 0;
576+
resource_size_t children_add_size = 0;
562577

563578
if (!b_res)
564579
return;
@@ -579,10 +594,15 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
579594
size += r_size;
580595
else
581596
size1 += r_size;
597+
598+
if (add_head)
599+
children_add_size += get_res_add_size(add_head, r);
582600
}
583601
}
584602
size0 = calculate_iosize(size, min_size, size1,
585603
resource_size(b_res), 4096);
604+
if (children_add_size > add_size)
605+
add_size = children_add_size;
586606
size1 = (!add_head || (add_head && !add_size)) ? size0 :
587607
calculate_iosize(size, min_size+add_size, size1,
588608
resource_size(b_res), 4096);
@@ -624,6 +644,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
624644
int order, max_order;
625645
struct resource *b_res = find_free_bus_resource(bus, type);
626646
unsigned int mem64_mask = 0;
647+
resource_size_t children_add_size = 0;
627648

628649
if (!b_res)
629650
return 0;
@@ -665,6 +686,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
665686
if (order > max_order)
666687
max_order = order;
667688
mem64_mask &= r->flags & IORESOURCE_MEM_64;
689+
690+
if (add_head)
691+
children_add_size += get_res_add_size(add_head, r);
668692
}
669693
}
670694
align = 0;
@@ -681,6 +705,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
681705
align += aligns[order];
682706
}
683707
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
708+
if (children_add_size > add_size)
709+
add_size = children_add_size;
684710
size1 = (!add_head || (add_head && !add_size)) ? size0 :
685711
calculate_memsize(size, min_size+add_size, 0,
686712
resource_size(b_res), min_align);

0 commit comments

Comments
 (0)