From patchwork Fri Apr 21 05:04:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 753131 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3w8Nyq6wR4z9s73 for ; Fri, 21 Apr 2017 15:07:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1035406AbdDUFGm (ORCPT ); Fri, 21 Apr 2017 01:06:42 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:36102 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1035320AbdDUFFu (ORCPT ); Fri, 21 Apr 2017 01:05:50 -0400 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v3L55bkP027625 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 Apr 2017 05:05:37 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.14.4) with ESMTP id v3L55a5O005986 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 Apr 2017 05:05:37 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id v3L55aRW016163; Fri, 21 Apr 2017 05:05:36 GMT Received: from dhcp-whq-twvpn-3-vpnpool-10-159-248-209.vpn.oracle.com (/69.181.250.163) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 20 Apr 2017 22:05:36 -0700 From: Yinghai Lu To: Bjorn Helgaas , David Miller , Benjamin Herrenschmidt Cc: Wei Yang , Khalid Aziz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64 Date: Thu, 20 Apr 2017 22:04:57 -0700 Message-Id: <20170421050500.13957-11-yinghai@kernel.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170421050500.13957-1-yinghai@kernel.org> References: <20170421050500.13957-1-yinghai@kernel.org> X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org If any bridge up to root only have 32bit pref mmio, We don't need to treat device non-pref mmio64 as as pref mmio64. We need to move pci_bridge_check_ranges calling early. For parent bridges pref mmio BAR may not allocated by BIOS, res flags is still 0, we need to have it correct set before we check them for child device resources. -v2: check all bus resources instead of just res[15]. Signed-off-by: Yinghai Lu Tested-by: Khalid Aziz --- drivers/pci/setup-bus.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 3de66e6..b3fd314 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -735,6 +735,29 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i) return -EINVAL; } +static bool pci_up_path_over_pref_mem64(struct pci_bus *bus) +{ + if (pci_is_root_bus(bus)) + return true; + + if (bus->self) { + int i; + bool found = false; + struct resource *res; + + pci_bus_for_each_resource(bus, res, i) + if (res->flags & IORESOURCE_MEM_64) { + found = true; + break; + } + + if (!found) + return false; + } + + return pci_up_path_over_pref_mem64(bus->parent); +} + int pci_resource_pref_compatible(const struct pci_dev *dev, struct resource *res) { @@ -743,7 +766,8 @@ int pci_resource_pref_compatible(const struct pci_dev *dev, if ((res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_MEM_64) && - dev->on_all_pcie_path) + dev->on_all_pcie_path && + pci_up_path_over_pref_mem64(dev->bus)) return res->flags | IORESOURCE_PREFETCH; return res->flags; @@ -1236,6 +1260,10 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) struct resource *b_res; int ret; + if (!pci_is_root_bus(bus) && + (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI) + pci_bridge_check_ranges(bus); + list_for_each_entry(dev, &bus->devices, bus_list) { struct pci_bus *b = dev->subordinate; if (!b) @@ -1263,7 +1291,6 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) break; case PCI_CLASS_BRIDGE_PCI: - pci_bridge_check_ranges(bus); if (bus->self->is_hotplug_bridge) { additional_io_size = pci_hotplug_io_size; additional_mem_size = pci_hotplug_mem_size;