Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp770842pxf; Thu, 1 Apr 2021 13:07:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyPFKu3GIbNPS638VY2iu0mpkbNKThQtgCYeCE9secI1TpDC0G7msFQR+8MTNXyoxZKKYsp X-Received: by 2002:a05:6402:35c8:: with SMTP id z8mr11866786edc.341.1617307648277; Thu, 01 Apr 2021 13:07:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617307648; cv=none; d=google.com; s=arc-20160816; b=meqgeP79XMw/hULhsSqQOZrFboOZm8U4XnZgoxsr0kIWSizvax7lfEIEJHHJUX8+3Z 5yBbpUs2A+xGiCHjtDFRrTl3oCbmvWOIAg6UFqNwjMVo6QSMb+6z/29oBf7cea+tv8LU IDrRWLY1YGtnEn2Fc3zX61Wr1hriTPo2g77QSeJenaRw7hgxfzEta/b3bcydaNpf9j+/ K3Vk7X16EHk3f40Hh02eLhi4jSPNY7ZAySnw6TjtMnZDh5/ypfEGAm0D5FkTP1XiIpb9 CWiXuG36bXkn95HLi9GUR5KPQF4SkWGvoSajxUifMXjT35veXtI1DSRIHpANlg8toq4S xm3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=1hhBMzz4uwlqxaxfvop5BpCa8xHjO7FZGl1x+RXXiD4=; b=BttcnW/QT9GngoJfO9oCpPLNzeUFwTJNMCi+hgkHeO2PnOaHv/xiAFljFcZEbin1C7 9aAvEQcHCZKc7CbPGHu86xSd+QR7EBOMc4FPLGcAtESN5bzVb47QU4ADMMeIPxq8XUK6 2g5k1xpiaPWdITIESmZ2kNhRHC5eSGQJ5LAXmESsn+X70rR6pGEfqbSXZPvHmUKhTcCv eBSnVrOSTVkBPUPOvGN6dLltGp74M/Ic8/iXAjSbOqk8DSCe7FfAJiiitC+u4w5M3dmH kpVGSfte5mrRHQvl/jTvuav9PX78GdYf21PPVBv/J4L+u7fkC1M9u7lUUpVlSwh3bq+k DMXQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id kl9si4811401ejc.271.2021.04.01.13.07.04; Thu, 01 Apr 2021 13:07:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235674AbhDAUDe (ORCPT + 99 others); Thu, 1 Apr 2021 16:03:34 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:45358 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235636AbhDAUDb (ORCPT ); Thu, 1 Apr 2021 16:03:31 -0400 Received: from 1-171-223-121.dynamic-ip.hinet.net ([1.171.223.121] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1lRx86-0006Dm-G1; Thu, 01 Apr 2021 13:12:59 +0000 From: Kai-Heng Feng To: bhelgaas@google.com Cc: Kai-Heng Feng , linux-pci@vger.kernel.org (open list:PCI SUBSYSTEM), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v2] PCI: Coalesce contiguous regions for host bridges Date: Thu, 1 Apr 2021 21:12:52 +0800 Message-Id: <20210401131252.531935-1-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Built-in graphics on HP EliteDesk 805 G6 doesn't work because graphics can't get the BAR it needs: [ 0.611504] pci_bus 0000:00: root bus resource [mem 0x10020200000-0x100303fffff window] [ 0.611505] pci_bus 0000:00: root bus resource [mem 0x10030400000-0x100401fffff window] ... [ 0.638083] pci 0000:00:08.1: bridge window [mem 0xd2000000-0xd23fffff] [ 0.638086] pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100401fffff 64bit pref] [ 0.962086] pci 0000:00:08.1: can't claim BAR 15 [mem 0x10030000000-0x100401fffff 64bit pref]: no compatible bridge window [ 0.962086] pci 0000:00:08.1: [mem 0x10030000000-0x100401fffff 64bit pref] clipped to [mem 0x10030000000-0x100303fffff 64bit pref] [ 0.962086] pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100303fffff 64bit pref] [ 0.962086] pci 0000:07:00.0: can't claim BAR 0 [mem 0x10030000000-0x1003fffffff 64bit pref]: no compatible bridge window [ 0.962086] pci 0000:07:00.0: can't claim BAR 2 [mem 0x10040000000-0x100401fffff 64bit pref]: no compatible bridge window However, the root bus has two contiguous regions that can contain the child resource requested. Bjorn Helgaas pointed out that we can simply coalesce contiguous regions for host bridges, since host bridge don't have _SRS. So do that accordingly to make child resource can be contained. This change makes the graphics works on the system in question. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212013 Suggested-by: Bjorn Helgaas Signed-off-by: Kai-Heng Feng --- v2: - Coalesce all contiguous regresion in pci_register_host_bridge(), if conditions are met. drivers/pci/probe.c | 49 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 953f15abc850..3607ce7402b4 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ @@ -874,14 +875,30 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus) dev_set_msi_domain(&bus->dev, d); } +static int res_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct resource_entry *entry1, *entry2; + + entry1 = container_of(a, struct resource_entry, node); + entry2 = container_of(b, struct resource_entry, node); + + if (entry1->res->flags != entry2->res->flags) + return entry1->res->flags > entry2->res->flags; + + if (entry1->offset != entry2->offset) + return entry1->offset > entry2->offset; + + return entry1->res->start > entry2->res->start; +} + static int pci_register_host_bridge(struct pci_host_bridge *bridge) { struct device *parent = bridge->dev.parent; - struct resource_entry *window, *n; + struct resource_entry *window, *next, *n; struct pci_bus *bus, *b; - resource_size_t offset; + resource_size_t offset, next_offset; LIST_HEAD(resources); - struct resource *res; + struct resource *res, *next_res; char addr[64], *fmt; const char *name; int err; @@ -959,11 +976,35 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE) dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n"); + /* Sort and coalesce contiguous windows */ + list_sort(NULL, &resources, res_cmp); + resource_list_for_each_entry_safe(window, n, &resources) { + if (list_is_last(&window->node, &resources)) + break; + + next = list_next_entry(window, node); + offset = window->offset; + res = window->res; + next_offset = next->offset; + next_res = next->res; + + if (res->flags != next_res->flags || offset != next_offset) + continue; + + if (res->end + 1 == next_res->start) { + next_res->start = res->start; + res->flags = res->start = res->end = 0; + } + } + /* Add initial resources to the bus */ resource_list_for_each_entry_safe(window, n, &resources) { - list_move_tail(&window->node, &bridge->windows); offset = window->offset; res = window->res; + if (!res->end) + continue; + + list_move_tail(&window->node, &bridge->windows); if (res->flags & IORESOURCE_BUS) pci_bus_insert_busn_res(bus, bus->number, res->end); -- 2.30.2