linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: Yinghai Lu <yinghai@kernel.org>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Gu Zheng <guz.fnst@cn.fujitsu.com>,
	Guo Chao <yan@linux.vnet.ibm.com>,
	"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Myron Stowe <myron.stowe@gmail.com>,
	Benjamin Herrenschmidt <benh@au1.ibm.com>,
	linux-scsi@vger.kernel.org, Matthew Garrett <mjg59@srcf.ucam.org>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH 3/9] ACPI / hotplug / PCI: Use global PCI rescan-remove locking
Date: Fri, 10 Jan 2014 15:24:41 +0100	[thread overview]
Message-ID: <1889108.hSyl0lYrWr@vostro.rjw.lan> (raw)
In-Reply-To: <20440867.YaQfKrcfsQ@vostro.rjw.lan>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Multiple race conditions are possible between the ACPI-based PCI
hotplug (ACPIPHP) and the generic PCI bus rescan and device removal
that can be triggered via sysfs.

To avoid those race conditions make the ACPIPHP code use global PCI
rescan-remove locking.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/pci/hotplug/acpiphp.h      |    5 +++-
 drivers/pci/hotplug/acpiphp_core.c |    2 -
 drivers/pci/hotplug/acpiphp_glue.c |   43 ++++++++++++++++++++++++++++++++-----
 3 files changed, 43 insertions(+), 7 deletions(-)

Index: linux-pm/drivers/pci/hotplug/acpiphp.h
===================================================================
--- linux-pm.orig/drivers/pci/hotplug/acpiphp.h
+++ linux-pm/drivers/pci/hotplug/acpiphp.h
@@ -77,6 +77,8 @@ struct acpiphp_bridge {
 
 	/* PCI-to-PCI bridge device */
 	struct pci_dev *pci_dev;
+
+	bool is_going_away;
 };
 
 
@@ -150,6 +152,7 @@ struct acpiphp_attention_info
 /* slot flags */
 
 #define SLOT_ENABLED		(0x00000001)
+#define SLOT_IS_GOING_AWAY	(0x00000002)
 
 /* function flags */
 
@@ -169,7 +172,7 @@ void acpiphp_unregister_hotplug_slot(str
 typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
 
 int acpiphp_enable_slot(struct acpiphp_slot *slot);
-int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
+int acpiphp_disable_slot(struct acpiphp_slot *slot);
 u8 acpiphp_get_power_status(struct acpiphp_slot *slot);
 u8 acpiphp_get_attention_status(struct acpiphp_slot *slot);
 u8 acpiphp_get_latch_status(struct acpiphp_slot *slot);
Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c
===================================================================
--- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c
+++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c
@@ -432,6 +432,7 @@ static void cleanup_bridge(struct acpiph
 					pr_err("failed to remove notify handler\n");
 			}
 		}
+		slot->flags |= SLOT_IS_GOING_AWAY;
 		if (slot->slot)
 			acpiphp_unregister_hotplug_slot(slot);
 	}
@@ -439,6 +440,8 @@ static void cleanup_bridge(struct acpiph
 	mutex_lock(&bridge_mutex);
 	list_del(&bridge->list);
 	mutex_unlock(&bridge_mutex);
+
+	bridge->is_going_away = true;
 }
 
 /**
@@ -757,6 +760,10 @@ static void acpiphp_check_bridge(struct
 {
 	struct acpiphp_slot *slot;
 
+	/* Bail out if the bridge is going away. */
+	if (bridge->is_going_away)
+		return;
+
 	list_for_each_entry(slot, &bridge->slots, node) {
 		struct pci_bus *bus = slot->bus;
 		struct pci_dev *dev, *tmp;
@@ -827,6 +834,8 @@ void acpiphp_check_host_bridge(acpi_hand
 	}
 }
 
+static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
+
 static void hotplug_event(acpi_handle handle, u32 type, void *data)
 {
 	struct acpiphp_context *context = data;
@@ -856,6 +865,9 @@ static void hotplug_event(acpi_handle ha
 		} else {
 			struct acpiphp_slot *slot = func->slot;
 
+			if (slot->flags & SLOT_IS_GOING_AWAY)
+				break;
+
 			mutex_lock(&slot->crit_sect);
 			enable_slot(slot);
 			mutex_unlock(&slot->crit_sect);
@@ -871,6 +883,9 @@ static void hotplug_event(acpi_handle ha
 			struct acpiphp_slot *slot = func->slot;
 			int ret;
 
+			if (slot->flags & SLOT_IS_GOING_AWAY)
+				break;
+
 			/*
 			 * Check if anything has changed in the slot and rescan
 			 * from the parent if that's the case.
@@ -900,9 +915,11 @@ static void hotplug_event_work(void *dat
 	acpi_handle handle = context->handle;
 
 	acpi_scan_lock_acquire();
+	pci_lock_rescan_remove();
 
 	hotplug_event(handle, type, context);
 
+	pci_unlock_rescan_remove();
 	acpi_scan_lock_release();
 	acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL);
 	put_bridge(context->func.parent);
@@ -1070,12 +1087,19 @@ void acpiphp_remove_slots(struct pci_bus
  */
 int acpiphp_enable_slot(struct acpiphp_slot *slot)
 {
+	pci_lock_rescan_remove();
+
+	if (slot->flags & SLOT_IS_GOING_AWAY)
+		return -ENODEV;
+
 	mutex_lock(&slot->crit_sect);
 	/* configure all functions */
 	if (!(slot->flags & SLOT_ENABLED))
 		enable_slot(slot);
 
 	mutex_unlock(&slot->crit_sect);
+
+	pci_unlock_rescan_remove();
 	return 0;
 }
 
@@ -1083,10 +1107,12 @@ int acpiphp_enable_slot(struct acpiphp_s
  * acpiphp_disable_and_eject_slot - power off and eject slot
  * @slot: ACPI PHP slot
  */
-int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
+static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
 {
 	struct acpiphp_func *func;
-	int retval = 0;
+
+	if (slot->flags & SLOT_IS_GOING_AWAY)
+		return -ENODEV;
 
 	mutex_lock(&slot->crit_sect);
 
@@ -1104,9 +1130,18 @@ int acpiphp_disable_and_eject_slot(struc
 		}
 
 	mutex_unlock(&slot->crit_sect);
-	return retval;
+	return 0;
 }
 
+int acpiphp_disable_slot(struct acpiphp_slot *slot)
+{
+	int ret;
+
+	pci_lock_rescan_remove();
+	ret = acpiphp_disable_and_eject_slot(slot);
+	pci_unlock_rescan_remove();
+	return ret;
+}
 
 /*
  * slot enabled:  1
@@ -1117,7 +1152,6 @@ u8 acpiphp_get_power_status(struct acpip
 	return (slot->flags & SLOT_ENABLED);
 }
 
-
 /*
  * latch   open:  1
  * latch closed:  0
@@ -1127,7 +1161,6 @@ u8 acpiphp_get_latch_status(struct acpip
 	return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI);
 }
 
-
 /*
  * adapter presence : 1
  *          absence : 0
Index: linux-pm/drivers/pci/hotplug/acpiphp_core.c
===================================================================
--- linux-pm.orig/drivers/pci/hotplug/acpiphp_core.c
+++ linux-pm/drivers/pci/hotplug/acpiphp_core.c
@@ -156,7 +156,7 @@ static int disable_slot(struct hotplug_s
 	pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
 	/* disable the specified slot */
-	return acpiphp_disable_and_eject_slot(slot->acpi_slot);
+	return acpiphp_disable_slot(slot->acpi_slot);
 }
 
 


  parent reply	other threads:[~2014-01-10 14:17 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-26  1:28 [PATCH v2 00/10] PCI: Double removing fix and allocate 64bit mmio pref Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 01/10] PCI: Use device_release_driver in pci_stop_root_bus Yinghai Lu
2013-11-27  1:09   ` Rafael J. Wysocki
2013-11-26  1:28 ` [PATCH v2 02/10] PCI: Move back pci_proc_attach_devices calling Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 03/10] PCI: Move resources and bus_list releasing to pci_release_dev Yinghai Lu
2013-11-27  1:15   ` Rafael J. Wysocki
2013-11-27  2:15     ` Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 04/10] PCI: Destroy pci dev only once Yinghai Lu
2013-11-26  3:38   ` Bjorn Helgaas
2013-11-26 19:34     ` Yinghai Lu
2013-11-26 20:13       ` Yinghai Lu
2013-11-27  1:24         ` Rafael J. Wysocki
2013-11-27  2:26           ` Yinghai Lu
2013-11-29 23:38             ` Rafael J. Wysocki
2013-11-29 23:45               ` Rafael J. Wysocki
2013-11-30  0:31                 ` Rafael J. Wysocki
2013-11-30 21:37                   ` Rafael J. Wysocki
2013-11-30 22:27                     ` Yinghai Lu
2013-12-01  1:24                       ` Rafael J. Wysocki
2013-12-02  1:29                         ` Rafael J. Wysocki
2013-12-02 14:49                           ` Rafael J. Wysocki
2013-12-05 22:40                             ` Bjorn Helgaas
2013-12-06  1:21                               ` Rafael J. Wysocki
2013-12-06  6:29                                 ` Yinghai Lu
2014-01-10 14:20                                 ` [PATCH 0/9] PCI: Eliminate race conditions between hotplug and sysfs rescan/remove (Was: Re: [PATCH v2 04/10] PCI: Destroy pci dev only once) Rafael J. Wysocki
2014-01-10 14:22                                   ` [PATCH 1/9] PCI: Global rescan-remove lock Rafael J. Wysocki
2014-01-10 14:23                                   ` [PATCH 2/9] ACPI / PCI: Use global PCI rescan-remove locking in PCI root hotplug Rafael J. Wysocki
2014-01-10 14:24                                   ` Rafael J. Wysocki [this message]
2014-01-10 14:25                                   ` [PATCH 4/9] PCMCIA / cardbus: Use global PCI rescan-remove locking Rafael J. Wysocki
2014-01-10 14:26                                   ` [PATCH 5/9] PCI / hotplug: " Rafael J. Wysocki
2014-01-10 14:27                                   ` [PATCH 6/9] platform / x86: " Rafael J. Wysocki
2014-01-10 14:27                                   ` [PATCH 7/9] MPT / PCI: Use pci_stop_and_remove_bus_device_locked() Rafael J. Wysocki
2014-01-10 14:28                                   ` [PATCH 8/9] powerpc / eeh_driver: Use global PCI rescan-remove locking Rafael J. Wysocki
2014-01-15 13:36                                     ` [Update][PATCH " Rafael J. Wysocki
2014-01-15 17:38                                       ` Bjorn Helgaas
2014-01-10 14:29                                   ` [PATCH 9/9] Xen / PCI: " Rafael J. Wysocki
2014-01-15 18:02                                   ` [PATCH 0/9] PCI: Eliminate race conditions between hotplug and sysfs rescan/remove (Was: Re: [PATCH v2 04/10] PCI: Destroy pci dev only once) Bjorn Helgaas
2013-12-06  6:52                             ` [PATCH v2 04/10] PCI: Destroy pci dev only once Yinghai Lu
2013-12-07  1:27                               ` Rafael J. Wysocki
2013-12-08  3:31                                 ` Yinghai Lu
2013-12-08  3:50                                   ` Greg Kroah-Hartman
2013-12-09 15:24                                     ` Ethan Zhao
2013-12-09 19:08                                       ` Greg Kroah-Hartman
2013-12-10  7:43                                         ` Ethan Zhao
2014-01-13  1:03                                 ` [PATCH] PCI / remove: Check parent kobject in pci_destroy_dev() (was: Re: [PATCH v2 04/10] PCI: Destroy pci dev only once) Rafael J. Wysocki
2013-11-27  1:17       ` [PATCH v2 04/10] PCI: Destroy pci dev only once Rafael J. Wysocki
2013-11-26  1:28 ` [PATCH v2 05/10] PCI: pcibus address to resource converting take bus directly Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 06/10] PCI: Add pcibios_bus_addr_to_res() Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 07/10] PCI: Try to allocate mem64 above 4G at first Yinghai Lu
2013-11-26  4:15   ` Bjorn Helgaas
2013-11-26 20:14     ` Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 08/10] PCI: Try best to allocate pref mmio 64bit above 4g Yinghai Lu
2013-11-26  4:17   ` Bjorn Helgaas
2013-11-26  6:59     ` Guo Chao
2013-11-26 17:53       ` Bjorn Helgaas
2013-11-26 22:00         ` Yinghai Lu
2013-11-26 22:01           ` Bjorn Helgaas
2013-11-27  0:33             ` Yinghai Lu
2013-11-26  1:28 ` [PATCH v2 09/10] PCI: Sort pci root bus resources list Yinghai Lu
2013-11-26  4:18   ` Bjorn Helgaas
2013-11-26  1:28 ` [PATCH v2 10/10] intel-gtt: Read 64bit for gmar_bus_addr Yinghai Lu
2013-11-26  3:46   ` Bjorn Helgaas
2013-11-26 19:35     ` Yinghai Lu
2013-12-11 18:48       ` Bjorn Helgaas
2013-12-11 19:58         ` Yinghai Lu
2013-12-21  0:27   ` Bjorn Helgaas
2013-12-21  1:19     ` Yinghai Lu
2013-12-21 18:50       ` Bjorn Helgaas
2013-12-23 22:33         ` Bjorn Helgaas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1889108.hSyl0lYrWr@vostro.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=benh@au1.ibm.com \
    --cc=bhelgaas@google.com \
    --cc=guz.fnst@cn.fujitsu.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=myron.stowe@gmail.com \
    --cc=rafael.j.wysocki@intel.com \
    --cc=yan@linux.vnet.ibm.com \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).