From patchwork Fri Sep 14 16:14:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Miroshnichenko X-Patchwork-Id: 10601021 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-2.web.codeaurora.org (Postfix) with ESMTP id 623B114BD for ; Fri, 14 Sep 2018 16:21:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 488A12AD92 for ; Fri, 14 Sep 2018 16:21:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3C6612BBE0; Fri, 14 Sep 2018 16:21:36 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 C46912AD92 for ; Fri, 14 Sep 2018 16:21:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728236AbeINVgp (ORCPT ); Fri, 14 Sep 2018 17:36:45 -0400 Received: from mta-01.yadro.com ([89.207.88.251]:60242 "EHLO mta-01.yadro.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727842AbeINVgp (ORCPT ); Fri, 14 Sep 2018 17:36:45 -0400 Received: from localhost (unknown [127.0.0.1]) by mta-01.yadro.com (Postfix) with ESMTP id 91578418F9; Fri, 14 Sep 2018 16:14:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=yadro.com; h= content-type:content-type:mime-version:references:in-reply-to :x-mailer:message-id:date:date:subject:subject:from:from :received:received:received; s=mta-01; t=1536941651; x= 1538756052; bh=SKrDtpNn4YSQKcsVB1OaeMOWHwjsrxY+lpoSWVb/1GQ=; b=I 40PvnhMS3hmr0D043zydVy5UN7SH9jQEkDq9OjGPoStBhzDkvBbxkrSalvkk4tQr jByUiz3+xN9vPYikbqJqrEXVZv+rmUEVfuTLZmA/rHU86N/sulh3uAt8sakx3VWl UCq9eAyTMUCub/pdCCSfBEsBGqtHImdTVow7tiGayU= X-Virus-Scanned: amavisd-new at yadro.com Received: from mta-01.yadro.com ([127.0.0.1]) by localhost (mta-01.yadro.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CRQUpRlf-5NM; Fri, 14 Sep 2018 19:14:11 +0300 (MSK) Received: from T-EXCH-02.corp.yadro.com (t-exch-02.corp.yadro.com [172.17.10.102]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mta-01.yadro.com (Postfix) with ESMTPS id 0B7044122E; Fri, 14 Sep 2018 19:14:11 +0300 (MSK) Received: from NB-148.yadro.com (172.17.15.60) by T-EXCH-02.corp.yadro.com (172.17.10.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.669.32; Fri, 14 Sep 2018 19:14:10 +0300 From: Sergey Miroshnichenko To: CC: Bjorn Helgaas , , Sergey Miroshnichenko Subject: [PATCH RFC 2/4] PCI: Release and reassign resources from the root during rescan Date: Fri, 14 Sep 2018 19:14:02 +0300 Message-ID: <20180914161404.4685-3-s.miroshnichenko@yadro.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180914161404.4685-1-s.miroshnichenko@yadro.com> References: <20180914161404.4685-1-s.miroshnichenko@yadro.com> MIME-Version: 1.0 X-Originating-IP: [172.17.15.60] X-ClientProxiedBy: T-EXCH-01.corp.yadro.com (172.17.10.101) To T-EXCH-02.corp.yadro.com (172.17.10.102) 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 If assigned resources don't contain holes to fit memory for hotplugged devices, these conflicting resources must be freed, sorted and reassigned. When resources are finally allocated and written to BARs, it's time to update bridge windows with pci_setup_bridge(). Signed-off-by: Sergey Miroshnichenko --- drivers/pci/pci.h | 8 ++++++++ drivers/pci/probe.c | 35 ++++++++++++++++++++++++++++++++++- drivers/pci/setup-bus.c | 12 ++++-------- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6e0d1528d471..cb157630f8d7 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -224,6 +224,11 @@ enum pci_bar_type { pci_bar_mem64, /* A 64-bit memory BAR */ }; +enum release_type { + leaf_only, + whole_subtree, +}; + int pci_configure_extended_tags(struct pci_dev *dev, void *ign); bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int crs_timeout); @@ -240,6 +245,9 @@ void __pci_bus_size_bridges(struct pci_bus *bus, void __pci_bus_assign_resources(const struct pci_bus *bus, struct list_head *realloc_head, struct list_head *fail_head); +void pci_bus_release_bridge_resources(struct pci_bus *bus, + unsigned long type, + enum release_type rel_type); bool pci_bus_clip_resource(struct pci_dev *dev, int idx); void pci_reassigndev_resource_alignment(struct pci_dev *dev); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bdaafc48dc4c..2c2b853454c2 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -3113,6 +3113,25 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, } EXPORT_SYMBOL(pci_scan_bus); +static void pci_setup_new_bridges(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + struct pci_bus *child; + + if (!pci_dev_is_added(dev)) + continue; + + child = dev->subordinate; + if (child) + pci_setup_new_bridges(child); + } + + if (bus->self) + pci_setup_bridge(bus); +} + /** * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices * @bridge: PCI bridge for the bus to scan @@ -3189,11 +3208,25 @@ static void pci_bus_reset_done(struct pci_bus *bus) unsigned int pci_rescan_bus(struct pci_bus *bus) { unsigned int max; + struct pci_bus *root = bus; + + while (!pci_is_root_bus(root)) + root = root->parent; if (pci_has_flag(PCI_MOVABLE_BARS)) pci_bus_reset_prepare(bus); max = pci_scan_child_bus(bus); - pci_assign_unassigned_bus_resources(bus); + if (pci_has_flag(PCI_MOVABLE_BARS)) { + pci_bus_release_bridge_resources(bus, IORESOURCE_IO, whole_subtree); + pci_bus_release_bridge_resources(bus, IORESOURCE_MEM, whole_subtree); + pci_bus_release_bridge_resources(bus, + IORESOURCE_MEM_64 | IORESOURCE_PREFETCH, + whole_subtree); + pci_assign_unassigned_root_bus_resources(root); + } else { + pci_assign_unassigned_bus_resources(bus); + } + pci_setup_new_bridges(bus); if (pci_has_flag(PCI_MOVABLE_BARS)) pci_bus_reset_done(bus); pci_bus_add_devices(bus); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 79b1824e83b4..fd5675bb501f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1244,7 +1244,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) case PCI_CLASS_BRIDGE_PCI: pci_bridge_check_ranges(bus); - if (bus->self->is_hotplug_bridge) { + if (bus->self->is_hotplug_bridge && !pci_has_flag(PCI_MOVABLE_BARS)) { additional_io_size = pci_hotplug_io_size; additional_mem_size = pci_hotplug_mem_size; } @@ -1582,17 +1582,13 @@ static void pci_bridge_release_resources(struct pci_bus *bus, } } -enum release_type { - leaf_only, - whole_subtree, -}; /* * try to release pci bridge resources that is from leaf bridge, * so we can allocate big new one later */ -static void pci_bus_release_bridge_resources(struct pci_bus *bus, - unsigned long type, - enum release_type rel_type) +void pci_bus_release_bridge_resources(struct pci_bus *bus, + unsigned long type, + enum release_type rel_type) { struct pci_dev *dev; bool is_leaf_bridge = true;