diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | drivers/base/dd.c | 8 | ||||
-rw-r--r-- | include/linux/device.h | 8 | ||||
-rw-r--r-- | include/linux/module.h | 2 | ||||
-rw-r--r-- | kernel/module.c | 12 |
5 files changed, 27 insertions, 6 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 61ab1628a057..e89fdd5aa605 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -943,6 +943,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. auto selects the default scheme, which automatically enables eagerfpu restore for xsaveopt. + 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 diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2ad33b21888c..7a2fa5dcead7 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -419,7 +419,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 { diff --git a/include/linux/device.h b/include/linux/device.h index 7857b46c548b..77b7cd9e5467 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -201,10 +201,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. @@ -216,7 +218,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus); * drivers. */ enum probe_type { - PROBE_SYNCHRONOUS, + PROBE_DEFAULT_STRATEGY, PROBE_PREFER_ASYNCHRONOUS, }; diff --git a/include/linux/module.h b/include/linux/module.h index c883b86ea964..f46a47d3c0dc 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -257,6 +257,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; diff --git a/kernel/module.c b/kernel/module.c index 24d1f31d02f2..ea941bc327d5 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3107,7 +3107,7 @@ static noinline 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); @@ -3240,8 +3240,16 @@ 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; |