From patchwork Wed Jan 15 13:36:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 311129 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 87DE22C0092 for ; Thu, 16 Jan 2014 00:22:41 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751896AbaAONWi (ORCPT ); Wed, 15 Jan 2014 08:22:38 -0500 Received: from v094114.home.net.pl ([79.96.170.134]:57112 "HELO v094114.home.net.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751684AbaAONWh (ORCPT ); Wed, 15 Jan 2014 08:22:37 -0500 Received: from afdp144.neoplus.adsl.tpnet.pl [95.49.93.144] (HELO vostro.rjw.lan) by serwer1319399.home.pl [79.96.170.134] with SMTP (IdeaSmtpServer v0.80) id d3d20c93ca435bd1; Wed, 15 Jan 2014 14:22:35 +0100 From: "Rafael J. Wysocki" To: Bjorn Helgaas Cc: Yinghai Lu , "Rafael J. Wysocki" , Gu Zheng , Guo Chao , "linux-pci@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Mika Westerberg , Myron Stowe , Benjamin Herrenschmidt , linux-scsi@vger.kernel.org, Matthew Garrett , Konrad Rzeszutek Wilk Subject: [Update][PATCH 8/9] powerpc / eeh_driver: Use global PCI rescan-remove locking Date: Wed, 15 Jan 2014 14:36:36 +0100 Message-ID: <1476201.kR505WbUas@vostro.rjw.lan> User-Agent: KMail/4.11.3 (Linux/3.13.0-rc8+; KDE/4.11.3; x86_64; ; ) In-Reply-To: <4447911.Q1f9tEzrXs@vostro.rjw.lan> References: <1385429290-25397-1-git-send-email-yinghai@kernel.org> <20440867.YaQfKrcfsQ@vostro.rjw.lan> <4447911.Q1f9tEzrXs@vostro.rjw.lan> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Rafael J. Wysocki Subject: powerpc / eeh_driver: Use global PCI rescan-remove locking Race conditions are theoretically possible between the PCI device addition and removal in the PPC64 PCI error recovery driver and the generic PCI bus rescan and device removal that can be triggered via sysfs. To avoid those race conditions make PPC64 PCI error recovery driver use global PCI rescan-remove locking around PCI device addition and removal. Signed-off-by: Rafael J. Wysocki --- The previous version had wrong function names in the last hunk, sorry about that. Rafael --- arch/powerpc/kernel/eeh_driver.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 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 Index: linux-pm/arch/powerpc/kernel/eeh_driver.c =================================================================== --- linux-pm.orig/arch/powerpc/kernel/eeh_driver.c +++ linux-pm/arch/powerpc/kernel/eeh_driver.c @@ -369,7 +369,9 @@ static void *eeh_rmv_device(void *data, edev->mode |= EEH_DEV_DISCONNECTED; (*removed)++; + pci_lock_rescan_remove(); pci_stop_and_remove_bus_device(dev); + pci_unlock_rescan_remove(); return NULL; } @@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_p * into pcibios_add_pci_devices(). */ eeh_pe_state_mark(pe, EEH_PE_KEEP); - if (bus) + if (bus) { + pci_lock_rescan_remove(); pcibios_remove_pci_devices(bus); - else if (frozen_bus) + pci_unlock_rescan_remove(); + } else if (frozen_bus) { eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); + } /* Reset the pci controller. (Asserts RST#; resets config space). * Reconfigure bridges and devices. Don't try to bring the system @@ -429,6 +434,8 @@ static int eeh_reset_device(struct eeh_p if (rc) return rc; + pci_lock_rescan_remove(); + /* Restore PE */ eeh_ops->configure_bridge(pe); eeh_pe_restore_bars(pe); @@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_p pe->tstamp = tstamp; pe->freeze_count = cnt; + pci_unlock_rescan_remove(); return 0; } @@ -618,8 +626,11 @@ perm_error: eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); /* Shut down the device drivers for good. */ - if (frozen_bus) + if (frozen_bus) { + pci_lock_rescan_remove(); pcibios_remove_pci_devices(frozen_bus); + pci_unlock_rescan_remove(); + } } static void eeh_handle_special_event(void) @@ -692,6 +703,7 @@ static void eeh_handle_special_event(voi if (rc == 2 || rc == 1) eeh_handle_normal_event(pe); else { + pci_lock_rescan_remove(); list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { phb_pe = eeh_phb_pe_get(hose); @@ -703,6 +715,7 @@ static void eeh_handle_special_event(voi eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); pcibios_remove_pci_devices(bus); } + pci_unlock_rescan_remove(); } }