From patchwork Mon Mar 30 16:50:14 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Chiang X-Patchwork-Id: 15160 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2UGsDGf018391 for ; Mon, 30 Mar 2009 16:54:15 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756693AbZC3QuX (ORCPT ); Mon, 30 Mar 2009 12:50:23 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756690AbZC3QuW (ORCPT ); Mon, 30 Mar 2009 12:50:22 -0400 Received: from g1t0026.austin.hp.com ([15.216.28.33]:8816 "EHLO g1t0026.austin.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756631AbZC3QuU (ORCPT ); Mon, 30 Mar 2009 12:50:20 -0400 Received: from smtp2.fc.hp.com (smtp.fc.hp.com [15.11.136.114]) by g1t0026.austin.hp.com (Postfix) with ESMTP id 92A9BC230; Mon, 30 Mar 2009 16:50:18 +0000 (UTC) Received: from localhost.localdomain (lart.fc.hp.com [15.11.146.31]) by smtp2.fc.hp.com (Postfix) with ESMTP id 692322BCAAE; Mon, 30 Mar 2009 16:26:09 +0000 (UTC) Received: from bob.kio (localhost [127.0.0.1]) by localhost.localdomain (Postfix) with ESMTP id 33BB226143; Mon, 30 Mar 2009 10:50:14 -0600 (MDT) Subject: [PATCH v2 2/3] PCI Hotplug: acpiphp: grab refcount on p2p subordinate bus To: jbarnes@virtuousgeek.org From: Alex Chiang Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Kenji Kaneshige Date: Mon, 30 Mar 2009 10:50:14 -0600 Message-ID: <20090330165014.18855.67275.stgit@bob.kio> In-Reply-To: <20090330164737.18855.7137.stgit@bob.kio> References: <20090330164737.18855.7137.stgit@bob.kio> User-Agent: StGit/0.14.3.347.g594a MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org If a logical hot unplug (remove) is performed on a bridge claimed by acpiphp and then acpiphp is unloaded, we will encounter an oops. This is because acpiphp will access the bridge's subordinate bus, which was released by the user's prior hot unplug. The solution is to grab a reference on the subordinate PCI bus. This will prevent the bus from release until acpiphp is unloaded. Reported-by: Kenji Kaneshige Signed-off-by: Alex Chiang Reviewed-by: Kenji Kaneshige Tested-by: Kenji Kaneshige --- drivers/pci/hotplug/acpiphp_glue.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 803d9dd..a33794d 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -38,6 +38,8 @@ * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() * when the bridge is scanned and it loses a refcount when the bridge * is removed. + * - When a P2P bridge is present, we elevate the refcount on the subordinate + * bus. It loses the refcount when the the driver unloads. */ #include @@ -440,6 +442,12 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) goto err; } + /* + * Grab a ref to the subordinate PCI bus in case the bus is + * removed via PCI core logical hotplug. The ref pins the bus + * (which we access during module unload). + */ + get_device(&bridge->pci_bus->dev); spin_lock_init(&bridge->res_lock); init_bridge_misc(bridge); @@ -619,6 +627,12 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) slot = next; } + /* + * Only P2P bridges have a pci_dev + */ + if (bridge->pci_dev) + put_device(&bridge->pci_bus->dev); + pci_dev_put(bridge->pci_dev); list_del(&bridge->list); kfree(bridge);