Commit 2efddb55 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Revert "driver core: shut down devices asynchronously"



This reverts commit 8064952c.

The series is being reverted before -rc1 as there are still reports of
lockups on shutdown, so it's not quite ready for "prime time."

Reported-by: default avatarAndrey Skvortsov <andrej.skvortzov@gmail.com>
Link: https://lore.kernel.org/r/ZvMkkhyJrohaajuk@skv.local


Cc: Christoph Hellwig <hch@lst.de>
Cc: David Jeffery <djeffery@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Cc: Laurence Oberman <loberman@redhat.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ec1fcbae
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
 * shared outside of the drivers/base/ directory.
 *
 */
#include <linux/async.h>
#include <linux/notifier.h>

/**
@@ -98,8 +97,6 @@ struct driver_private {
 *	the device; typically because it depends on another driver getting
 *	probed first.
 * @async_driver - pointer to device driver awaiting probe via async_probe
 * @shutdown_after - used during device shutdown to ensure correct shutdown
 *	ordering.
 * @device - pointer back to the struct device that this structure is
 * associated with.
 * @dead - This device is currently either in the process of or has been
@@ -117,7 +114,6 @@ struct device_private {
	struct list_head deferred_probe;
	const struct device_driver *async_driver;
	char *deferred_probe_reason;
	async_cookie_t shutdown_after;
	struct device *device;
	u8 dead:1;
};
+1 −53
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
 */

#include <linux/acpi.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <linux/cleanup.h>
#include <linux/cpufreq.h>
@@ -3525,7 +3524,6 @@ static int device_private_init(struct device *dev)
	klist_init(&dev->p->klist_children, klist_children_get,
		   klist_children_put);
	INIT_LIST_HEAD(&dev->p->deferred_probe);
	dev->p->shutdown_after = 0;
	return 0;
}

@@ -4781,8 +4779,6 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
}
EXPORT_SYMBOL_GPL(device_change_owner);

static ASYNC_DOMAIN(sd_domain);

static void shutdown_one_device(struct device *dev)
{
	/* hold lock to avoid race with probe/release */
@@ -4818,34 +4814,12 @@ static void shutdown_one_device(struct device *dev)
		put_device(dev->parent);
}

/**
 * shutdown_one_device_async
 * @data: the pointer to the struct device to be shutdown
 * @cookie: not used
 *
 * Shuts down one device, after waiting for shutdown_after to complete.
 * shutdown_after should be set to the cookie of the last child or consumer
 * of this device to be shutdown (if any), or to the cookie of the previous
 * device to be shut down for devices that don't enable asynchronous shutdown.
 */
static void shutdown_one_device_async(void *data, async_cookie_t cookie)
{
	struct device *dev = data;

	async_synchronize_cookie_domain(dev->p->shutdown_after + 1, &sd_domain);

	shutdown_one_device(dev);
}

/**
 * device_shutdown - call ->shutdown() on each device to shutdown.
 */
void device_shutdown(void)
{
	struct device *dev, *parent;
	async_cookie_t cookie = 0;
	struct device_link *link;
	int idx;

	wait_for_device_probe();
	device_block_probing();
@@ -4876,37 +4850,11 @@ void device_shutdown(void)
		list_del_init(&dev->kobj.entry);
		spin_unlock(&devices_kset->list_lock);


		/*
		 * Set cookie for devices that will be shut down synchronously
		 */
		if (!dev->driver || !dev->driver->async_shutdown_enable)
			dev->p->shutdown_after = cookie;

		get_device(dev);
		get_device(parent);

		cookie = async_schedule_domain(shutdown_one_device_async,
					       dev, &sd_domain);
		/*
		 * Ensure parent & suppliers wait for this device to shut down
		 */
		if (parent) {
			parent->p->shutdown_after = cookie;
			put_device(parent);
		}

		idx = device_links_read_lock();
		list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
				device_links_read_lock_held())
			link->supplier->p->shutdown_after = cookie;
		device_links_read_unlock(idx);
		put_device(dev);
		shutdown_one_device(dev);

		spin_lock(&devices_kset->list_lock);
	}
	spin_unlock(&devices_kset->list_lock);
	async_synchronize_full_domain(&sd_domain);
}

/*
+0 −2
Original line number Diff line number Diff line
@@ -56,7 +56,6 @@ enum probe_type {
 * @mod_name:	Used for built-in modules.
 * @suppress_bind_attrs: Disables bind/unbind via sysfs.
 * @probe_type:	Type of the probe (synchronous or asynchronous) to use.
 * @async_shutdown_enable: Enables devices to be shutdown asynchronously.
 * @of_match_table: The open firmware table.
 * @acpi_match_table: The ACPI match table.
 * @probe:	Called to query the existence of a specific device,
@@ -103,7 +102,6 @@ struct device_driver {

	bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */
	enum probe_type probe_type;
	bool async_shutdown_enable;

	const struct of_device_id	*of_match_table;
	const struct acpi_device_id	*acpi_match_table;