From patchwork Thu Feb 25 02:12:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 8416781 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 64A36C0553 for ; Thu, 25 Feb 2016 02:24:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 79E2C2034A for ; Thu, 25 Feb 2016 02:24:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5CEDE20377 for ; Thu, 25 Feb 2016 02:24:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932625AbcBYCXr (ORCPT ); Wed, 24 Feb 2016 21:23:47 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:41160 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932518AbcBYCXp (ORCPT ); Wed, 24 Feb 2016 21:23:45 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u1P2DJbX019045 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 25 Feb 2016 02:13:20 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u1P2DJrq013870 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 25 Feb 2016 02:13:19 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u1P2DIm0003166; Thu, 25 Feb 2016 02:13:18 GMT Received: from userv0022.oracle.com (/10.132.126.176) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 24 Feb 2016 18:13:17 -0800 From: Yinghai Lu To: Bjorn Helgaas , David Miller , Benjamin Herrenschmidt , Wei Yang , TJ , Yijing Wang , Khalid Aziz Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH v10 25/59] PCI: Use correct align for optional only resources during sorting Date: Wed, 24 Feb 2016 18:12:16 -0800 Message-Id: <1456366370-28995-26-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1456366370-28995-1-git-send-email-yinghai@kernel.org> References: <1456366370-28995-1-git-send-email-yinghai@kernel.org> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP During sorting before assign, we only put resource with non-zero align in the sorted list, so for optional resources that required size is 0 and only have optional parts, we need to have correct align. While treating SRIOV as optional resources, we always read alignment for SRIOV bars every time, so they are ok. Hotplug bridge resources are using STARTALIGN so it is ok when size is 0 if we have correct start for them. Later we want to treat the ROM BAR as optional resource, and it has SIZEALIGN, so align=size will be 0. We need to find a way to get align for them. We can use optional resource align instead in that case, and it is ok for SRIOV path and hotplug bridge resource path. We need to pass realloc list from sizing stage to sorting stage, and get entry from realloc list 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 | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index aae1de0..a0905e9 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -145,9 +145,42 @@ 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; + struct pci_dev_resource *dev_res; + + if (r_align || !realloc_head) + return r_align; + + dev_res = res_to_dev_res(realloc_head, r); + if (!dev_res || !dev_res->add_size) + return r_align; + + orig_start = r->start; + orig_end = r->end; + r->end += dev_res->add_size; + if ((r->flags & IORESOURCE_STARTALIGN)) { + resource_size_t r_size = resource_size(r); + + r->start = dev_res->min_align; + r->end = r->start + 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 +198,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 +216,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 +231,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 +248,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) @@ -507,7 +542,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); } @@ -520,7 +555,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); }