From patchwork Mon Jul 27 23:30:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 500895 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 21CA41402E8 for ; Tue, 28 Jul 2015 09:34:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755009AbbG0XeG (ORCPT ); Mon, 27 Jul 2015 19:34:06 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:37717 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932084AbbG0XeC (ORCPT ); Mon, 27 Jul 2015 19:34:02 -0400 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t6RNVeQw001078 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 27 Jul 2015 23:31:40 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t6RNVe9A015566 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 27 Jul 2015 23:31:40 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t6RNVeFn029551; Mon, 27 Jul 2015 23:31:40 GMT Received: from linux-siqj.site (/107.215.0.145) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 27 Jul 2015 16:31:39 -0700 From: Yinghai Lu To: Bjorn Helgaas , David Miller , Benjamin Herrenschmidt , Wei Yang , TJ , Yijing Wang Cc: Andrew Morton , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu , stable@vger.kernel.org Subject: [PATCH v3 46/51] PCI: Don't release fixed resource for realloc Date: Mon, 27 Jul 2015 16:30:04 -0700 Message-Id: <1438039809-24957-47-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1438039809-24957-1-git-send-email-yinghai@kernel.org> References: <1438039809-24957-1-git-send-email-yinghai@kernel.org> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org We should not release bridge resource if there is fixed resources under it, otherwise the children firmware would stop working. Reported-by: Paul Johnson Suggested-by: Bjorn Helgaas Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=92351 Signed-off-by: Yinghai Lu Cc: stable@vger.kernel.org --- drivers/pci/setup-bus.c | 6 ++++-- include/linux/ioport.h | 2 +- kernel/resource.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 63a5d4cf..dcbbe04 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -2070,14 +2070,16 @@ static void pci_bridge_release_resources(struct pci_bus *bus, r = &b_res[idx]; - if (!r->parent) + if (!r->parent || r->flags & IORESOURCE_PCI_FIXED) return; /* * if there are children under that, we should release them * all */ - release_child_resources(r); + if (!release_child_resources(r)) + return; + if (!release_resource(r)) { type = old_flags = r->flags & type_mask; dev_printk(KERN_DEBUG, &dev->dev, "resource %d %pR released\n", diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 388e3ae..27dbb18 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -141,7 +141,7 @@ extern struct resource iomem_resource; extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); -void release_child_resources(struct resource *new); +bool release_child_resources(struct resource *new); extern void reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name); diff --git a/kernel/resource.c b/kernel/resource.c index 697b8ca..4e43f9b 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -276,11 +276,35 @@ static void __release_child_resources(struct resource *r) } } -void release_child_resources(struct resource *r) +static bool __has_fixed_child_resources(struct resource *r) { + struct resource *p; + + p = r->child; + while (p) { + if (p->flags & IORESOURCE_PCI_FIXED) + return true; + + if (__has_fixed_child_resources(p)) + return true; + + p = p->sibling; + } + + return false; +} + +bool release_child_resources(struct resource *r) +{ + bool fixed; + write_lock(&resource_lock); - __release_child_resources(r); + fixed = __has_fixed_child_resources(r); + if (!fixed) + __release_child_resources(r); write_unlock(&resource_lock); + + return !fixed; } /**