From patchwork Tue Dec 10 06:54:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 299295 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 F11C22C007C for ; Tue, 10 Dec 2013 17:56:03 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751894Ab3LJGzp (ORCPT ); Tue, 10 Dec 2013 01:55:45 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:51555 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752000Ab3LJGzJ (ORCPT ); Tue, 10 Dec 2013 01:55:09 -0500 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id rBA6t4Ol022287 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 10 Dec 2013 06:55:05 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rBA6t30J026428 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 10 Dec 2013 06:55:03 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rBA6t2fq009133; Tue, 10 Dec 2013 06:55:02 GMT Received: from linux-siqj.site (/75.36.244.240) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 09 Dec 2013 22:55:02 -0800 From: Yinghai Lu To: Bjorn Helgaas Cc: Guo Chao , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH v4 5/5] PCI: Sort pci root bus resources list Date: Mon, 9 Dec 2013 22:54:44 -0800 Message-Id: <1386658484-15774-6-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1386658484-15774-1-git-send-email-yinghai@kernel.org> References: <1386658484-15774-1-git-send-email-yinghai@kernel.org> X-Source-IP: ucsinet21.oracle.com [156.151.31.93] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Some x86 systems expose above 4G 64bit mmio in _CRS as non-pref mmio range. [ 49.415281] PCI host bridge to bus 0000:00 [ 49.419921] pci_bus 0000:00: root bus resource [bus 00-1e] [ 49.426107] pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7] [ 49.433041] pci_bus 0000:00: root bus resource [io 0x1000-0x5fff] [ 49.440010] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff] [ 49.447768] pci_bus 0000:00: root bus resource [mem 0xfed8c000-0xfedfffff] [ 49.455532] pci_bus 0000:00: root bus resource [mem 0x90000000-0x9fffbfff] [ 49.463259] pci_bus 0000:00: root bus resource [mem 0x380000000000-0x381fffffffff] During assign unassigned 64bit mmio resource, it will go through every non-pref mmio for root bus in pci_bus_alloc_resource(). As the loop is with pci_bus_for_each_resource(), and could have chance to use under 4G mmio range instead of above 4G mmio range if the requested range is not big enough, even it could handle above 4G 64bit pref mmio. For root bus, we can order list from high to low in pci_add_resource_offset(), during creating root bus, it will still keep the same order in final bus resource list. pci_acpi_scan_root ==> add_resources ==> pci_add_resource_offset: # Add to temp resources ==> pci_create_root_bus ==> pci_bus_add_resource # add to final bus resources. After that, we can make sure 64bit pref mmio for pci bridges will be allocated higest of mmio non-pref, and in this case it is above 4G instead of under 4G. Signed-off-by: Yinghai Lu --- drivers/pci/bus.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 45d8de5..7798cd3 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -21,7 +21,8 @@ void pci_add_resource_offset(struct list_head *resources, struct resource *res, resource_size_t offset) { - struct pci_host_bridge_window *window; + struct pci_host_bridge_window *window, *tmp; + struct list_head *n; window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL); if (!window) { @@ -31,7 +32,17 @@ void pci_add_resource_offset(struct list_head *resources, struct resource *res, window->res = res; window->offset = offset; - list_add_tail(&window->list, resources); + + /* Keep list sorted according to res end */ + n = resources; + list_for_each_entry(tmp, resources, list) + if (window->res->end > tmp->res->end) { + n = &tmp->list; + break; + } + + /* Insert it just before n */ + list_add_tail(&window->list, n); } EXPORT_SYMBOL(pci_add_resource_offset);