From patchwork Thu Mar 26 16:31:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 6100891 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 28877BF90F for ; Thu, 26 Mar 2015 16:34:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E3FF9203A0 for ; Thu, 26 Mar 2015 16:34:53 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C7AE92037C for ; Thu, 26 Mar 2015 16:34:51 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YbAhp-0006cc-To; Thu, 26 Mar 2015 16:32:29 +0000 Received: from mail-ie0-x22d.google.com ([2607:f8b0:4001:c03::22d]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YbAhi-0006Tz-3i for linux-arm-kernel@lists.infradead.org; Thu, 26 Mar 2015 16:32:23 +0000 Received: by ieclw3 with SMTP id lw3so50698956iec.2 for ; Thu, 26 Mar 2015 09:32:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=0pRszIEtMuvsqvZiuSaRf/UDBnfEMXi2eFrBAyShDvs=; b=jkdBpkeupkgkDawzBeVWo9KFLN4iJq0mbeHA9njGfJv64xVacHVEEWSmf3AFgTyFMM uamkPnGv6G4svirnI5Kn2yjKcGeuMSsw1YgD89mWmagn9y3mKUj0Qcme5mYDDPqdTzMd cJ5EFe0Qmxbu5bvHa2pbQhHZis1FdidxESJrTdA8LDoWrweKQ0dlkzkgMKVmUTafoS5K AwWXh0parganp1AY8oB26mib/nkj8XfA3I24W//bWLMY1h+gP+L7Zz6ntUPdXvvwJZbD RaBTypP49HwOgfxlEvwiTZkpDJ2mOyY5viE/Kh/siA838+nBp2UevUOzTHBolTWpyzVD IooQ== MIME-Version: 1.0 X-Received: by 10.107.155.13 with SMTP id d13mr22190914ioe.29.1427387518296; Thu, 26 Mar 2015 09:31:58 -0700 (PDT) Received: by 10.64.208.43 with HTTP; Thu, 26 Mar 2015 09:31:58 -0700 (PDT) In-Reply-To: <1427168064-8657-11-git-send-email-wangyijing@huawei.com> References: <1427168064-8657-1-git-send-email-wangyijing@huawei.com> <1427168064-8657-11-git-send-email-wangyijing@huawei.com> Date: Thu, 26 Mar 2015 09:31:58 -0700 X-Google-Sender-Auth: 8kYlRtzSu4I335ypa5jyKGBhjZY Message-ID: Subject: Re: [PATCH v8 10/30] PCI: Introduce pci_host_bridge_list to manage host bridges From: Yinghai Lu To: Yijing Wang X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150326_093222_268035_4BE3009C X-CRM114-Status: GOOD ( 24.18 ) X-Spam-Score: -0.5 (/) Cc: Liviu Dudau , Rusty Russell , Russell King , Arnd Bergmann , Marc Zyngier , "linux-pci@vger.kernel.org" , the arch/x86 maintainers , linux-m68k@lists.linux-m68k.org, Linux Kernel Mailing List , "David S. Miller" , linux-alpha@vger.kernel.org, Tony Luck , Geert Uytterhoeven , Benjamin Herrenschmidt , Bjorn Helgaas , "linux-ia64@vger.kernel.org" , Thomas Gleixner , Guan Xuetao , Jiang Liu , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Mon, Mar 23, 2015 at 8:34 PM, Yijing Wang wrote: > Introduce pci_host_bridge_list to manage pci host > bridges in system, this make us have the ability > to check whether the new host would conflict with > existing one. Then we could remove bus alreay exist > check in __pci_create_root_bus(). Can we use bus_type instead? Then we can use bus_find_device for the host_bridge enumeration. Please refer the patches that I sent out couple years ago. Thanks Yinghai Subject: [PATCH] PCI: Add for_each_pci_host_bridge() and pci_get_next_host_bridge Now we have pci_root_buses list, and there is lots of iteration with list_of_each of it, that is not safe after we add pci root bus hotplug support after booting stage. Also pci_find_next_bus is pretty misleading name, and it is only finding next root bus instead of regular pci bus. Add pci_get_next_host_bridge and use bus_find_device in driver core to iterate host bridge and the same time get root bus. In folllowing patches will replace searching root bus with searching host_bridge. after using with that host-bridge, will need to call put device to release reference if break early from the loop. After those replacing, we even could kill pci_root_buses list. -v2: fixes compiling error when CONFIG_PCI is not defined that Fengguang found. Signed-off-by: Yinghai Lu --- drivers/pci/search.c | 24 ++++++++++++++++++++++++ include/linux/pci.h | 9 +++++++++ 2 files changed, 33 insertions(+) Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -409,6 +409,8 @@ struct pci_host_bridge { }; #define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) +#define for_each_pci_host_bridge(d) while ((d = pci_get_next_host_bridge(d)) != NULL) + void pci_set_host_bridge_release(struct pci_host_bridge *bridge, void (*release_fn)(struct pci_host_bridge *), void *release_data); @@ -831,6 +833,7 @@ int pci_find_ht_capability(struct pci_de int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); struct pci_bus *pci_find_next_bus(const struct pci_bus *from); +struct pci_host_bridge *pci_get_next_host_bridge(struct pci_host_bridge *from); struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from); struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, @@ -1447,6 +1450,12 @@ static inline int pci_domain_nr(struct p static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } +static inline struct pci_host_bridge *pci_get_next_host_bridge( + struct pci_host_bridge *host_bridge) +{ + return NULL; +} + #define dev_is_pci(d) (false) #define dev_is_pf(d) (false) #define dev_num_vf(d) (0) Index: linux-2.6/drivers/pci/search.c =================================================================== --- linux-2.6.orig/drivers/pci/search.c +++ linux-2.6/drivers/pci/search.c @@ -231,6 +231,30 @@ struct pci_dev *pci_get_domain_bus_and_s } EXPORT_SYMBOL(pci_get_domain_bus_and_slot); +static int match_pci_host_bridge(struct device *dev, void *data) +{ + return 1; +} + +struct pci_host_bridge *pci_get_next_host_bridge(struct pci_host_bridge *from) +{ + struct device *dev; + struct device *dev_start = NULL; + struct pci_host_bridge *bridge = NULL; + + WARN_ON(in_interrupt()); + if (from) + dev_start = &from->dev; + dev = bus_find_device(&pci_host_bridge_bus_type, dev_start, NULL, + match_pci_host_bridge); + if (dev) + bridge = to_pci_host_bridge(dev); + if (from) + put_device(&from->dev); + return bridge; +} +EXPORT_SYMBOL_GPL(pci_get_next_host_bridge); + static int match_pci_dev_by_id(struct device *dev, void *data) { struct pci_dev *pdev = to_pci_dev(dev);