Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757284AbcDHATP (ORCPT ); Thu, 7 Apr 2016 20:19:15 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:35215 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756968AbcDHATM (ORCPT ); Thu, 7 Apr 2016 20:19:12 -0400 From: Yinghai Lu To: Bjorn Helgaas , David Miller , Benjamin Herrenschmidt , Linus Torvalds Cc: Wei Yang , TJ , Yijing Wang , Khalid Aziz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH v11 22/60] PCI: Get new realloc size for bridge for last try Date: Thu, 7 Apr 2016 17:15:35 -0700 Message-Id: <1460074573-7481-23-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1460074573-7481-1-git-send-email-yinghai@kernel.org> References: <1460074573-7481-1-git-send-email-yinghai@kernel.org> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2132 Lines: 72 Current realloc path would not shrink bridge resource through pbus_size_mem() checking with the old size. That cause problem: when "required+optional" resource allocation fails, the cached bridge resource size will prevent "required" resource to get allocated smaller resource. Clear the old resource size for last try or third and later try. -v3: for last or third time and later. change reset_bridge_resource_size to static according to Fengguang. -v4: don't clear size for bridge's normal resources. Link: https://bugzilla.kernel.org/show_bug.cgi?id=81431 Tested-by: TJ Signed-off-by: Yinghai Lu --- drivers/pci/setup-bus.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 3dc4ac9..d3a39b7 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1738,6 +1738,17 @@ static enum enable_type pci_realloc_detect(struct pci_bus *bus, } #endif +static void reset_bridge_resource_size(struct pci_dev *dev, + struct resource *res) +{ + int idx = res - &dev->resource[0]; + + if (idx >= PCI_BRIDGE_RESOURCES && idx <= PCI_BRIDGE_RESOURCE_END) { + res->start = 0; + res->end = res->start - 1; + } +} + /* * first try will not touch pci bridge res * second and later try will clear small leaf bridge res @@ -1822,8 +1833,13 @@ again: res->start = fail_res->start; res->end = fail_res->end; res->flags = fail_res->flags; - if (fail_res->dev->subordinate) + if (fail_res->dev->subordinate) { res->flags = 0; + /* last or third times and later */ + if (tried_times + 1 == pci_try_num || + tried_times + 1 > 2) + reset_bridge_resource_size(fail_res->dev, res); + } } free_list(&fail_head); @@ -1897,8 +1913,11 @@ again: res->start = fail_res->start; res->end = fail_res->end; res->flags = fail_res->flags; - if (fail_res->dev->subordinate) + if (fail_res->dev->subordinate) { res->flags = 0; + /* last time */ + reset_bridge_resource_size(fail_res->dev, res); + } } free_list(&fail_head); -- 1.8.4.5