Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e29659b authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by Lingutla Chandrasekhar
Browse files

driver-core: add driver module asynchronous probe support



Some init systems may wish to express the desire to have device
drivers run their probe() code asynchronously.
This implements support for this and allows userspace to request
async probe as a preference through a generic shared device driver
module parameter, async_probe.

Implementation for async probe is supported through a module
parameter given that since synchronous probe has been prevalent
for years some userspace might exist which relies on the fact that
the device driver will probe synchronously and the assumption that
devices it provides will be immediately available after this.

Change-Id: Ic20ee2354b2efdcf3c0d02c407863af559ff86fa
Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@suse.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Git-commit: f2411da746985e60d4d087f3a43e271c61785927
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


Signed-off-by: default avatarLingutla Chandrasekhar <clingutla@codeaurora.org>
parent 21740ced
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -929,6 +929,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			Enable debug messages at boot time.  See
			Documentation/dynamic-debug-howto.txt for details.

	module.async_probe [KNL]
			Enable asynchronous probe on this module.

	early_ioremap_debug [KNL]
			Enable debug messages in early_ioremap support. This
			is useful for tracking down temporary early mappings
+7 −1
Original line number Diff line number Diff line
@@ -427,7 +427,13 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)

bool driver_allows_async_probing(struct device_driver *drv)
{
	return drv->probe_type == PROBE_PREFER_ASYNCHRONOUS;
	if (drv->probe_type == PROBE_PREFER_ASYNCHRONOUS)
		return true;

	if (drv->owner && drv->owner->async_probe_requested)
		return true;

	return false;
}

struct device_attach_data {
+5 −3
Original line number Diff line number Diff line
@@ -200,10 +200,12 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus);
 *	respective probe routines. This tells the core what to
 *	expect and prefer.
 *
 * @PROBE_SYNCHRONOUS: Default. Drivers expect their probe routines
 * @PROBE_DEFAULT_STRATEGY: Drivers expect their probe routines
 *	to run synchronously with driver and device registration
 *	(with the exception of -EPROBE_DEFER handling - re-probing
 *	always ends up being done asynchronously).
 *	always ends up being done asynchronously) unless user
 *	explicitly requested asynchronous probing via module
 *	parameter.
 * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which
 *	probing order is not essential for booting the system may
 *	opt into executing their probes asynchronously.
@@ -215,7 +217,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus);
 * drivers.
 */
enum probe_type {
	PROBE_SYNCHRONOUS,
	PROBE_DEFAULT_STRATEGY,
	PROBE_PREFER_ASYNCHRONOUS,
};

+2 −0
Original line number Diff line number Diff line
@@ -277,6 +277,8 @@ struct module {
	bool sig_ok;
#endif

	bool async_probe_requested;

	/* symbols that will be GPL-only in the near future. */
	const struct kernel_symbol *gpl_future_syms;
	const unsigned long *gpl_future_crcs;
+10 −3
Original line number Diff line number Diff line
@@ -3106,7 +3106,7 @@ static int do_init_module(struct module *mod)
	 *
	 * http://thread.gmane.org/gmane.linux.kernel/1420814
	 */
	if (current->flags & PF_USED_ASYNC)
	if (!mod->async_probe_requested && (current->flags & PF_USED_ASYNC))
		async_synchronize_full();

	mutex_lock(&module_mutex);
@@ -3236,8 +3236,15 @@ out:
static int unknown_module_param_cb(char *param, char *val, const char *modname,
				   void *arg)
{
	struct module *mod = arg;
	int ret;

	if (strcmp(param, "async_probe") == 0) {
		mod->async_probe_requested = true;
		return 0;
	}
	/* Check for magic 'dyndbg' arg */
	int ret = ddebug_dyndbg_module_param_cb(param, val, modname);
	ret = ddebug_dyndbg_module_param_cb(param, val, modname);
	if (ret != 0)
		pr_warn("%s: unknown parameter '%s' ignored\n", modname, param);
	return 0;