From patchwork Thu May 18 01:47:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Lin X-Patchwork-Id: 9732313 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 1A29B601BC for ; Thu, 18 May 2017 01:49:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8922286D2 for ; Thu, 18 May 2017 01:49:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9B56286E4; Thu, 18 May 2017 01:49:16 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3A640286D2 for ; Thu, 18 May 2017 01:49:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=iYAA82UinDidO3R10CnFr9wbfUGluD2vmFRDZMnqOl0=; b=ulF 4PEuMnRicrCFkVv5Es1XPfd92yoejXIzgO2O4zZP8x9PyG2HnjKjOLo2WEcWA0oBrG1HrMnfoCrUd 0Ah4/tCza7Lk+NzyvQ7plRdfpVDgycGETNOpKdlw+ymIZHRInW1Tet4mNUEOcQ6I7k0KUN/DhcPNy /1BVWzi+eawI8HdsPGR1o+LeSid4ZhsBwJayQuhUMiivldwBxK525twWZFmQ4/X/JQfoGpjFonsSH IURU4foR59usYxC0x9RG9GzMEYWCW+QDr8vtZc51MOuYM8ilqeNp8BUElpQtRMAZ16MNC97z+Q4MC upwHsvGjmHlN1PdrANzc/Mmm9Og5tkw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dBAYy-0003Y2-HY; Thu, 18 May 2017 01:49:12 +0000 Received: from lucky1.263xmail.com ([211.157.147.132]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dBAYu-0003ON-4t for linux-rockchip@lists.infradead.org; Thu, 18 May 2017 01:49:10 +0000 Received: from shawn.lin?rock-chips.com (unknown [192.168.167.156]) by lucky1.263xmail.com (Postfix) with ESMTP id 86C7E64318; Thu, 18 May 2017 09:48:40 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id 709CE308; Thu, 18 May 2017 09:48:39 +0800 (CST) X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: bhelgaas@google.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <3b60229f9b45794a06f0d40fac5ce92b> X-ATTACHMENT-NUM: 0 X-SENDER: lintao@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 18716L0MXOD; Thu, 18 May 2017 09:48:40 +0800 (CST) From: Shawn Lin To: Bjorn Helgaas Subject: [PATCH v2] PCI: use IDA to manage domain number if not getting it from DT Date: Thu, 18 May 2017 09:47:17 +0800 Message-Id: <1495072037-135458-1-git-send-email-shawn.lin@rock-chips.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170517_184908_540231_E2DB886F X-CRM114-Status: GOOD ( 15.58 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pci@vger.kernel.org, Jeffy Chen , Brian Norris , Shawn Lin , linux-rockchip@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP If not getting domain number from DT, the domain number will keep increasing once doing unbind/bind RC drivers. This could introduce pointless tree view of lspci as shows below: -+-[0001:00]---00.0-[01]----00.0 \-[0000:00]- The more test we do, the lengthier it would be. The more serious issue is that if attaching two hierarchies for two different domains belonging to two root bridges, so when doing unbind/bind test for one of them and keep the other, then the domain number would finally overflow and make the two hierarchies of devices share the some domain number but actually they shouldn't. So it looks like we need to invent a new indexing ID mechanism to manage domain number. This patch introduces idr to achieve our purpose. Cc: Brian Norris Cc: Jeffy Chen Signed-off-by: Shawn Lin --- Changes in v2: - add a remove wrapper - rename use_dt_domains to ida_domain and set this bit in pci_get_new_domain_nr and test it in the remove wrapper. drivers/pci/pci.c | 23 +++++++++++++++++------ drivers/pci/remove.c | 2 ++ include/linux/pci.h | 9 +++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b01bd5b..8affda5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -5340,19 +5341,29 @@ static void pci_no_domains(void) } #ifdef CONFIG_PCI_DOMAINS -static atomic_t __domain_nr = ATOMIC_INIT(-1); +DEFINE_IDA(__domain_nr); -int pci_get_new_domain_nr(void) +int pci_get_new_domain_nr(struct pci_bus *bus) { - return atomic_inc_return(&__domain_nr); + bus->ida_domain = true; + return ida_simple_get(&__domain_nr, 0, sizeof(u64), GFP_KERNEL); +} + +void pci_put_old_domain_nr(struct pci_bus *bus) +{ + if (bus->ida_domain) + ida_simple_remove(&__domain_nr, bus->domain_nr); } #ifdef CONFIG_PCI_DOMAINS_GENERIC -static int of_pci_bus_find_domain_nr(struct device *parent) +static int of_pci_bus_find_domain_nr(struct pci_bus *bus, + struct device *parent) { static int use_dt_domains = -1; int domain = -1; + bus->ida_domain = false; + if (parent) domain = of_get_pci_domain_nr(parent->of_node); /* @@ -5385,7 +5396,7 @@ static int of_pci_bus_find_domain_nr(struct device *parent) use_dt_domains = 1; } else if (domain < 0 && use_dt_domains != 1) { use_dt_domains = 0; - domain = pci_get_new_domain_nr(); + domain = pci_get_new_domain_nr(bus); } else { dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", parent->of_node->full_name); @@ -5397,7 +5408,7 @@ static int of_pci_bus_find_domain_nr(struct device *parent) int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) { - return acpi_disabled ? of_pci_bus_find_domain_nr(parent) : + return acpi_disabled ? of_pci_bus_find_domain_nr(bus, parent) : acpi_pci_bus_find_domain_nr(bus); } #endif diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 73a03d3..1bbbb37 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -157,6 +157,8 @@ void pci_remove_root_bus(struct pci_bus *bus) list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) pci_remove_bus_device(child); + + pci_put_old_domain_nr(bus); pci_remove_bus(bus); host_bridge->bus = NULL; diff --git a/include/linux/pci.h b/include/linux/pci.h index 33c2b0b..d4f6fb8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -513,6 +513,7 @@ struct pci_bus { unsigned char cur_bus_speed; /* enum pci_bus_speed */ #ifdef CONFIG_PCI_DOMAINS_GENERIC int domain_nr; + bool ida_domain; /* get domain number from IDA */ #endif char name[48]; @@ -1445,13 +1446,17 @@ static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) * configuration space. */ #ifdef CONFIG_PCI_DOMAINS +extern struct ida __domain_nr; extern int pci_domains_supported; -int pci_get_new_domain_nr(void); +int pci_get_new_domain_nr(struct pci_bus *bus); +void pci_put_old_domain_nr(struct pci_bus *bus); #else enum { pci_domains_supported = 0 }; static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } -static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } +static inline int pci_get_new_domain_nr(struct pci_bus *bus) +{ return -ENOSYS; } +static inline void pci_put_old_domain_nr(struct pci_bus *bus) { } #endif /* CONFIG_PCI_DOMAINS */ /*