From patchwork Fri Dec 7 06:25:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Myron Stowe X-Patchwork-Id: 204395 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 AA7422C00D2 for ; Fri, 7 Dec 2012 17:26:39 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946110Ab2LGG0E (ORCPT ); Fri, 7 Dec 2012 01:26:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43909 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1946003Ab2LGG0C (ORCPT ); Fri, 7 Dec 2012 01:26:02 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qB76Q0Qh010611 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 7 Dec 2012 01:26:00 -0500 Received: from amt.stowe ([10.3.113.3]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qB76PxL5031199; Fri, 7 Dec 2012 01:26:00 -0500 From: Myron Stowe Subject: [PATCH 11/15] PCI/ACPI: Fix latent refcount issue in acpi_pci_root_start() To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, yinghai@kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 06 Dec 2012 23:25:59 -0700 Message-ID: <20121207062559.11051.18764.stgit@amt.stowe> In-Reply-To: <20121207062454.11051.12739.stgit@amt.stowe> References: <20121207062454.11051.12739.stgit@amt.stowe> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org During early boot, the kernel performs ACPI enumeration in which host bridges are discovered (subsys_initcall(acpi_pci_root_init)). Later drivers, both built-in and modules such as the "ACPI PCI Slot Detection Driver ("pci_slot")", are loaded (module_init(acpi_pci_slot_init)) thus we end up with the following call chain: acpi_pci_root_start list_for_each_entry(..., acpi_pci_drivers, ...) driver->add(root) # always no-op; list empty pci_bus_add_devices acpi_pci_slot_init # module_init acpi_pci_register_driver(acpi_pci_slot_driver) list_for_each_entry(..., &acpi_pci_roots, ...) driver->add(root) # acpi_pci_slot_add() Note that for host bridges present at boot time the 'acpi_pci_drivers' list is always empty when acpi_pci_root_start() runs. However, during a Host Bridge hot-add event, the "pci_slot" sub-driver is already on the 'acpi_pci_drivers' list and we end up calling acpi_pci_slot_add() before pci_bus_add_devices() and encounter the following refcount WARNING: calling acpi_pci_slot_add(): pci_bus 0000:03: dev 00, created physical slot 1 ------------[ cut here ]------------ WARNING: at include/linux/kref.h:42 kobject_get+0x32/0x40() Call Trace: [] kobject_get+0x32/0x40 [] get_device+0x19/0x20 [] register_slot+0x216/0x26d [] acpi_walk_namespace+0x8a/0xc4 [] walk_p2p_bridge+0xf1/0x133 [] acpi_walk_namespace+0x8a/0xc4 [] acpi_pci_slot_add+0xe0/0x137 [] acpi_pci_root_start+0x3e/0x59 This patch fixes this latent issue by moving up pci_bus_add_devices() so that the refcount will be initialized before subsequent references, via driver additions from the 'acpi_pci_drivers' list, occur. Signed-off-by: Myron Stowe --- drivers/acpi/pci_root.c | 4 ++-- 1 files changed, 2 insertions(+), 2 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/acpi/pci_root.c b/drivers/acpi/pci_root.c index d890322..f9be8fb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -644,6 +644,8 @@ static int acpi_pci_root_start(struct acpi_device *device) struct acpi_pci_root *root = acpi_driver_data(device); struct acpi_pci_driver *driver; + pci_bus_add_devices(root->bus); + mutex_lock(&acpi_pci_root_lock); list_for_each_entry(driver, &acpi_pci_drivers, node) if (driver->add) @@ -651,8 +653,6 @@ static int acpi_pci_root_start(struct acpi_device *device) acpiphp_add_bridge(root); mutex_unlock(&acpi_pci_root_lock); - pci_bus_add_devices(root->bus); - return 0; }