From patchwork Wed Dec 16 15:16:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 7862461 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 4C72FBEEE5 for ; Wed, 16 Dec 2015 15:20:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 47ECB20148 for ; Wed, 16 Dec 2015 15:19:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1CADD2035E for ; Wed, 16 Dec 2015 15:19:58 +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 1a9DqV-0000tT-9x; Wed, 16 Dec 2015 15:18:27 +0000 Received: from mail-wm0-x233.google.com ([2a00:1450:400c:c09::233]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a9Dq6-0000e3-G6 for linux-arm-kernel@lists.infradead.org; Wed, 16 Dec 2015 15:18:04 +0000 Received: by mail-wm0-x233.google.com with SMTP id p187so5599307wmp.0 for ; Wed, 16 Dec 2015 07:17:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hUeEnFNnjnpYV7JXTSgYxPzg6UxJD3VbwxbrlazHj1o=; b=BIBx5eLnU6Tr+sM7COPKASFjZR42oB8Rpq7TbjR86uXutWKRFW7x5WZWbUarX+75w4 bfDbLHYb6Nrl0XC0N95LmEGoAY3C+j2O5kT/TFtpqX2BwnraVcn7TgbLODLJp5w8gHUU hc/uvb4o8GrglrT8tZeYa+lI0DyHPlfbjcxmQo5az5+ysMDaR/XAkyY5j4yy0DJWtoTz aPuQ3wmksOC/LvHpLAwkN9cUebE9ufkP3Zwg0El5ySyeOOep8QdGeL74ECxRSAz1Lotg 2RghwXv7ecBITy7lcDPL5/ns/PnAhh+tMSeIDTKAh30iVOkPUX2M78VDrNLHbn+D704d i7sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hUeEnFNnjnpYV7JXTSgYxPzg6UxJD3VbwxbrlazHj1o=; b=NJGO7wrP8ED3AOweRKLmSPH/ZyO94TDtd+ngG5eqe2sM4N73Zrm3vBwNEHERbAuuO1 YvKjpz7EqzMZw/NPWFnLhW2gJTwDengBBGfBBrMXdDqQtgquriIajwgp8dWJqioMPrKz g2335T9+keG5fjS362zV648NYKOuBQMWYFdndbJ7bCIKzJg/Yjnab8uphxUe3UZLGO3g f88mgD6l3zWoBFKnCzf+88Y3lvJH8uLEszgU6wvnezQ2BnHRW/YquKsyYXDvuFgx3c/8 gN3sLDxnm5QcNvlsietdNDK+FcibJmfIhlPRplS5gnzoFeEk/Nzb/o4ZqRreHFyxCumZ W+nQ== X-Gm-Message-State: ALoCoQnCvALggP4QcuTmv+AGCehF1y1N+L0I4LeuclBp/OjAti5zc/M3r8My/p688rrnHr8cgjVAihm7mTfqhJq+nBtnPPDgWg== X-Received: by 10.28.171.134 with SMTP id u128mr12667300wme.22.1450279060593; Wed, 16 Dec 2015 07:17:40 -0800 (PST) Received: from tn-HP-4.semihalf.local ([80.82.22.190]) by smtp.gmail.com with ESMTPSA id z17sm6438761wjq.1.2015.12.16.07.17.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Dec 2015 07:17:39 -0800 (PST) From: Tomasz Nowicki To: bhelgaas@google.com, arnd@arndb.de, will.deacon@arm.com, catalin.marinas@arm.com, rjw@rjwysocki.net, hanjun.guo@linaro.org, Lorenzo.Pieralisi@arm.com, okaya@codeaurora.org, jiang.liu@linux.intel.com, Stefano.Stabellini@eu.citrix.com Subject: [PATCH V2 01/23] x86, pci: Reorder logic of pci_mmconfig_insert() function Date: Wed, 16 Dec 2015 16:16:11 +0100 Message-Id: <1450278993-12664-2-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1450278993-12664-1-git-send-email-tn@semihalf.com> References: <1450278993-12664-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151216_071802_776053_9FAD9C8A X-CRM114-Status: GOOD ( 18.68 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jchandra@broadcom.com, jcm@redhat.com, linaro-acpi@lists.linaro.org, linux-pci@vger.kernel.org, Liviu.Dudau@arm.com, ddaney@caviumnetworks.com, Tomasz Nowicki , linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, robert.richter@caviumnetworks.com, Suravee.Suthikulpanit@amd.com, msalter@redhat.com, wangyijing@huawei.com, Tomasz Nowicki , tglx@linutronix.de, mw@semihalf.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 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 This patch is the first step for MMCONFIG refactoring process. Code that uses pci_mmcfg_lock will be moved to common file and become accessible for all architectures. pci_mmconfig_insert() cannot be moved so easily since it is mixing generic mmconfig code with x86 specific logic inside of mutual exclusive block guarded by pci_mmcfg_lock. To get rid of that constraint, we reorder actions as follow: 1. sanity check for mmconfig region presence, if we already have such region it doesn't make snese to alloc new mmconfig list entry 2. mmconfig entry allocation, no need to lock 3. insertion to iomem_resource has its own lock, no need to wrap it into mutex 4. insertion to mmconfig list can be done as the final step in separate function (candidate for further refactoring) and needs another mmconfig lookup to avoid race condition. Signed-off-by: Tomasz Nowicki Tested-by: Suravee Suthikulpanit --- arch/x86/pci/mmconfig-shared.c | 101 +++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index dd30b7e..c8bb9b0 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -720,6 +720,38 @@ static int __init pci_mmcfg_late_insert_resources(void) */ late_initcall(pci_mmcfg_late_insert_resources); +static int pci_mmconfig_inject(struct pci_mmcfg_region *cfg) +{ + struct pci_mmcfg_region *cfg_conflict; + int err = 0; + + mutex_lock(&pci_mmcfg_lock); + cfg_conflict = pci_mmconfig_lookup(cfg->segment, cfg->start_bus); + if (cfg_conflict) { + if (cfg_conflict->end_bus < cfg->end_bus) + pr_info(FW_INFO "MMCONFIG for " + "domain %04x [bus %02x-%02x] " + "only partially covers this bridge\n", + cfg_conflict->segment, cfg_conflict->start_bus, + cfg_conflict->end_bus); + err = -EEXIST; + goto out; + } + + if (pci_mmcfg_arch_map(cfg)) { + pr_warn("fail to map MMCONFIG %pR.\n", &cfg->res); + err = -ENOMEM; + goto out; + } else { + list_add_sorted(cfg); + pr_info("MMCONFIG at %pR (base %#lx)\n", + &cfg->res, (unsigned long)cfg->address); + } +out: + mutex_unlock(&pci_mmcfg_lock); + return err; +} + /* Add MMCFG information for host bridges */ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, phys_addr_t addr) @@ -734,63 +766,46 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, if (start > end) return -EINVAL; - mutex_lock(&pci_mmcfg_lock); + rcu_read_lock(); cfg = pci_mmconfig_lookup(seg, start); - if (cfg) { - if (cfg->end_bus < end) - dev_info(dev, FW_INFO - "MMCONFIG for " - "domain %04x [bus %02x-%02x] " - "only partially covers this bridge\n", - cfg->segment, cfg->start_bus, cfg->end_bus); - mutex_unlock(&pci_mmcfg_lock); + rcu_read_unlock(); + if (cfg) return -EEXIST; - } - if (!addr) { - mutex_unlock(&pci_mmcfg_lock); + if (!addr) return -EINVAL; - } - rc = -EBUSY; cfg = pci_mmconfig_alloc(seg, start, end, addr); - if (cfg == NULL) { + if (!cfg) { dev_warn(dev, "fail to add MMCONFIG (out of memory)\n"); - rc = -ENOMEM; - } else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) { + return -ENOMEM; + } + + rc = -EBUSY; + if (!pci_mmcfg_check_reserved(dev, cfg, 0)) { dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n", &cfg->res); - } else { - /* Insert resource if it's not in boot stage */ - if (pci_mmcfg_running_state) - tmp = insert_resource_conflict(&iomem_resource, - &cfg->res); - - if (tmp) { - dev_warn(dev, - "MMCONFIG %pR conflicts with " - "%s %pR\n", - &cfg->res, tmp->name, tmp); - } else if (pci_mmcfg_arch_map(cfg)) { - dev_warn(dev, "fail to map MMCONFIG %pR.\n", - &cfg->res); - } else { - list_add_sorted(cfg); - dev_info(dev, "MMCONFIG at %pR (base %#lx)\n", - &cfg->res, (unsigned long)addr); - cfg = NULL; - rc = 0; - } + goto error; } - if (cfg) { - if (cfg->res.parent) - release_resource(&cfg->res); - kfree(cfg); + /* Insert resource if it's not in boot stage */ + if (pci_mmcfg_running_state) + tmp = insert_resource_conflict(&iomem_resource, &cfg->res); + + if (tmp) { + dev_warn(dev, "MMCONFIG %pR conflicts with %s %pR\n", + &cfg->res, tmp->name, tmp); + goto error; } - mutex_unlock(&pci_mmcfg_lock); + rc = pci_mmconfig_inject(cfg); + if (!rc) + return 0; +error: + if (cfg->res.parent) + release_resource(&cfg->res); + kfree(cfg); return rc; }