Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756285AbbGFXlG (ORCPT ); Mon, 6 Jul 2015 19:41:06 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:17155 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756077AbbGFXka (ORCPT ); Mon, 6 Jul 2015 19:40:30 -0400 From: Yinghai Lu To: Bjorn Helgaas , David Miller , David Ahern , Benjamin Herrenschmidt , Wei Yang , TJ , Yijing Wang Cc: Andrew Morton , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH 03/36] PCI: Use correct align for optional only resources during sorting for resource allocation Date: Mon, 6 Jul 2015 16:38:53 -0700 Message-Id: <1436225966-27247-4-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1436225966-27247-1-git-send-email-yinghai@kernel.org> References: <1436225966-27247-1-git-send-email-yinghai@kernel.org> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4119 Lines: 129 During sorting before assign, we only put resource with non-zero align in the sorted list, so for optional resources that must part is 0 and only have addon parts, we need to have correct align. Use addon resource align instead in that case. Sorted list will contain must res align/size to 0/0 to hold spot for optional resources. And later we will treat the ROM BAR as optional resource with this support. The patch will pass realloc_head from sizing stage to sorting stage, and get entry from realloc and calculate align from the entry. Link: https://bugzilla.kernel.org/show_bug.cgi?id=81431 Reported-by: TJ Signed-off-by: Yinghai Lu --- drivers/pci/setup-bus.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 247d8fe..9f4c477 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -145,9 +145,38 @@ static resource_size_t get_res_add_align(struct list_head *head, return dev_res->min_align; } +static resource_size_t __pci_resource_alignment( + struct pci_dev *dev, + struct resource *r, + struct list_head *realloc_head) +{ + resource_size_t r_align = pci_resource_alignment(dev, r); + resource_size_t orig_start, orig_end; + + if (r_align || !realloc_head) + return r_align; + + orig_start = r->start; + orig_end = r->end; + r->end += get_res_add_size(realloc_head, r); + if ((r->flags & IORESOURCE_STARTALIGN)) { + resource_size_t r_size = resource_size(r); + resource_size_t add_align = get_res_add_align(realloc_head, r); + + r->start = add_align; + r->end = add_align + r_size - 1; + } + r_align = pci_resource_alignment(dev, r); + r->start = orig_start; + r->end = orig_end; + + return r_align; +} /* Sort resources by alignment */ -static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) +static void pdev_sort_resources(struct pci_dev *dev, + struct list_head *realloc_head, + struct list_head *head) { int i; @@ -165,7 +194,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) if (!(r->flags) || r->parent) continue; - r_align = pci_resource_alignment(dev, r); + r_align = __pci_resource_alignment(dev, r, realloc_head); if (!r_align) { dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", i, r); @@ -183,8 +212,9 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) list_for_each_entry(dev_res, head, list) { resource_size_t align; - align = pci_resource_alignment(dev_res->dev, - dev_res->res); + align = __pci_resource_alignment(dev_res->dev, + dev_res->res, + realloc_head); if (r_align > align) { n = &dev_res->list; @@ -197,6 +227,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) } static void __dev_sort_resources(struct pci_dev *dev, + struct list_head *realloc_head, struct list_head *head) { u16 class = dev->class >> 8; @@ -213,7 +244,7 @@ static void __dev_sort_resources(struct pci_dev *dev, return; } - pdev_sort_resources(dev, head); + pdev_sort_resources(dev, realloc_head, head); } static inline void reset_resource(struct resource *res) @@ -501,7 +532,7 @@ static void pdev_assign_resources_sorted(struct pci_dev *dev, { LIST_HEAD(head); - __dev_sort_resources(dev, &head); + __dev_sort_resources(dev, add_head, &head); __assign_resources_sorted(&head, add_head, fail_head); } @@ -514,7 +545,7 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus, LIST_HEAD(head); list_for_each_entry(dev, &bus->devices, bus_list) - __dev_sort_resources(dev, &head); + __dev_sort_resources(dev, realloc_head, &head); __assign_resources_sorted(&head, realloc_head, fail_head); } -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/