From patchwork Mon May 28 12:47:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 10432363 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 429A6601BE for ; Mon, 28 May 2018 12:48:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3286B286A8 for ; Mon, 28 May 2018 12:48:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2743D28831; Mon, 28 May 2018 12:48:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C43412876D for ; Mon, 28 May 2018 12:48:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937840AbeE1Ms0 (ORCPT ); Mon, 28 May 2018 08:48:26 -0400 Received: from mga03.intel.com ([134.134.136.65]:62720 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S937809AbeE1MsB (ORCPT ); Mon, 28 May 2018 08:48:01 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2018 05:48:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,452,1520924400"; d="scan'208";a="59182628" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 28 May 2018 05:47:57 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id ABC5529A; Mon, 28 May 2018 15:47:56 +0300 (EEST) From: Mika Westerberg To: Bjorn Helgaas , "Rafael J . Wysocki" Cc: Len Brown , Mario.Limonciello@dell.com, Michael Jamet , Yehezkel Bernat , Andy Shevchenko , Lukas Wunner , Mika Westerberg , linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH v8 1/7] PCI: Take all bridges into account when calculating bus numbers for extension Date: Mon, 28 May 2018 15:47:50 +0300 Message-Id: <20180528124756.78512-2-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528124756.78512-1-mika.westerberg@linux.intel.com> References: <20180528124756.78512-1-mika.westerberg@linux.intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When distributing extra buses between hotplug bridges for future extension we currently fail to take into account the fact that there might be non-hotplug bridges on the bus after the hotplug bridges. In this particular system we have following topology: 01:00.0 --+- 02:00.0 -- Thunderbolt host controller +- 02:01.0 (HotPlug+) \- 02:02.0 -- xHCI host controller Now, pci_scan_child_bus_extend() is supposed to distribute remaining bus numbers to the hotplug bridge at 02:01.0 but only after all bridges on that bus have been been accounted for. Since we don't check upfront that there will be another non-hotplug bridge after the hotplug bridge 02:01.0 it will inadvertently extend over the bus space of the non-hotplug bridge: pci 0000:01:00.0: PCI bridge to [bus 02-39] ... pci_bus 0000:04: [bus 04-39] extended by 0x35 pci_bus 0000:04: bus scan returning with max=39 pci_bus 0000:04: busn_res: [bus 04-39] end is updated to 39 pci 0000:02:02.0: scanning [bus 00-00] behind bridge, pass 1 pci_bus 0000:3a: scanning bus pci_bus 0000:3a: bus scan returning with max=3a pci_bus 0000:3a: busn_res: [bus 3a] end is updated to 3a pci_bus 0000:3a: [bus 3a] partially hidden behind bridge 0000:02 [bus 02-39] pci_bus 0000:3a: [bus 3a] partially hidden behind bridge 0000:01 [bus 01-39] pci_bus 0000:02: bus scan returning with max=3a pci_bus 0000:02: busn_res: [bus 02-39] end can not be updated to 3a Resulting 'lspci -t' output looks like this: +-1b.0-[01-39]----00.0-[02-3a]--+-00.0-[03]----00.0 ^^ +-01.0-[04-39]-- \-02.0-[3a]----00.0 ^^ The xHCI host controller (3a:00.0) behind downstream bridge at 02:02.0 is not usable anymore. To fix this reserve at least one bus for each bridge during scanning of already configured bridges. Then we use this information in the second scan to correct the available extra bus space for hotplug bridges. After this change the 'lspci -t' output is what is expected: +-1b.0-[01-39]----00.0-[02-39]--+-00.0-[03]----00.0 +-01.0-[04-38]-- \-02.0-[39]----00.0 Fixes: 1c02ea810065 ("PCI: Distribute available buses to hotplug-capable bridges") Reported-by: Mario Limonciello Signed-off-by: Mika Westerberg Reviewed-by: Rafael J. Wysocki Reviewed-by: Andy Shevchenko Cc: stable@vger.kernel.org --- drivers/pci/probe.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index d14e8f827d53..8f384e7ca2c2 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2634,7 +2634,14 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, for_each_pci_bridge(dev, bus) { cmax = max; max = pci_scan_bridge_extend(bus, dev, max, 0, 0); - used_buses += cmax - max; + /* + * Reserve one bus for each bridge now to avoid + * extending hotplug bridges too much during the second + * scan below. + */ + used_buses++; + if (cmax - max > 1) + used_buses += cmax - max - 1; } /* Scan bridges that need to be reconfigured */ @@ -2657,12 +2664,14 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, * bridges if any. */ buses = available_buses / hotplug_bridges; - buses = min(buses, available_buses - used_buses); + buses = min(buses, available_buses - used_buses + 1); } cmax = max; max = pci_scan_bridge_extend(bus, dev, cmax, buses, 1); - used_buses += max - cmax; + /* One bus is already accounted so don't add it again */ + if (max - cmax > 1) + used_buses += max - cmax - 1; } /*