aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@suse.com>2015-03-30 19:20:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-20 03:25:24 -0400
commitf2411da746985e60d4d087f3a43e271c61785927 (patch)
tree09b6c3b2abd4774f63e4a0d467e3c70daa52663e
parent765230b5f084863183aa8adb3405ab3f32c0b16e (diff)
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. Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--Documentation/kernel-parameters.txt3
-rw-r--r--drivers/base/dd.c8
-rw-r--r--include/linux/device.h8
-rw-r--r--include/linux/module.h2
-rw-r--r--kernel/module.c12
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.
943 auto selects the default scheme, which automatically 943 auto selects the default scheme, which automatically
944 enables eagerfpu restore for xsaveopt. 944 enables eagerfpu restore for xsaveopt.
945 945
946 module.async_probe [KNL]
947 Enable asynchronous probe on this module.
948
946 early_ioremap_debug [KNL] 949 early_ioremap_debug [KNL]
947 Enable debug messages in early_ioremap support. This 950 Enable debug messages in early_ioremap support. This
948 is useful for tracking down temporary early mappings 951 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)
419 419
420bool driver_allows_async_probing(struct device_driver *drv) 420bool driver_allows_async_probing(struct device_driver *drv)
421{ 421{
422 return drv->probe_type == PROBE_PREFER_ASYNCHRONOUS; 422 if (drv->probe_type == PROBE_PREFER_ASYNCHRONOUS)
423 return true;
424
425 if (drv->owner && drv->owner->async_probe_requested)
426 return true;
427
428 return false;
423} 429}
424 430
425struct device_attach_data { 431struct 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);
201 * respective probe routines. This tells the core what to 201 * respective probe routines. This tells the core what to
202 * expect and prefer. 202 * expect and prefer.
203 * 203 *
204 * @PROBE_SYNCHRONOUS: Default. Drivers expect their probe routines 204 * @PROBE_DEFAULT_STRATEGY: Drivers expect their probe routines
205 * to run synchronously with driver and device registration 205 * to run synchronously with driver and device registration
206 * (with the exception of -EPROBE_DEFER handling - re-probing 206 * (with the exception of -EPROBE_DEFER handling - re-probing
207 * always ends up being done asynchronously). 207 * always ends up being done asynchronously) unless user
208 * explicitly requested asynchronous probing via module
209 * parameter.
208 * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which 210 * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which
209 * probing order is not essential for booting the system may 211 * probing order is not essential for booting the system may
210 * opt into executing their probes asynchronously. 212 * opt into executing their probes asynchronously.
@@ -216,7 +218,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus);
216 * drivers. 218 * drivers.
217 */ 219 */
218enum probe_type { 220enum probe_type {
219 PROBE_SYNCHRONOUS, 221 PROBE_DEFAULT_STRATEGY,
220 PROBE_PREFER_ASYNCHRONOUS, 222 PROBE_PREFER_ASYNCHRONOUS,
221}; 223};
222 224
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 {
257 bool sig_ok; 257 bool sig_ok;
258#endif 258#endif
259 259
260 bool async_probe_requested;
261
260 /* symbols that will be GPL-only in the near future. */ 262 /* symbols that will be GPL-only in the near future. */
261 const struct kernel_symbol *gpl_future_syms; 263 const struct kernel_symbol *gpl_future_syms;
262 const unsigned long *gpl_future_crcs; 264 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)
3107 * 3107 *
3108 * http://thread.gmane.org/gmane.linux.kernel/1420814 3108 * http://thread.gmane.org/gmane.linux.kernel/1420814
3109 */ 3109 */
3110 if (current->flags & PF_USED_ASYNC) 3110 if (!mod->async_probe_requested && (current->flags & PF_USED_ASYNC))
3111 async_synchronize_full(); 3111 async_synchronize_full();
3112 3112
3113 mutex_lock(&module_mutex); 3113 mutex_lock(&module_mutex);
@@ -3240,8 +3240,16 @@ out:
3240static int unknown_module_param_cb(char *param, char *val, const char *modname, 3240static int unknown_module_param_cb(char *param, char *val, const char *modname,
3241 void *arg) 3241 void *arg)
3242{ 3242{
3243 struct module *mod = arg;
3244 int ret;
3245
3246 if (strcmp(param, "async_probe") == 0) {
3247 mod->async_probe_requested = true;
3248 return 0;
3249 }
3250
3243 /* Check for magic 'dyndbg' arg */ 3251 /* Check for magic 'dyndbg' arg */
3244 int ret = ddebug_dyndbg_module_param_cb(param, val, modname); 3252 ret = ddebug_dyndbg_module_param_cb(param, val, modname);
3245 if (ret != 0) 3253 if (ret != 0)
3246 pr_warn("%s: unknown parameter '%s' ignored\n", modname, param); 3254 pr_warn("%s: unknown parameter '%s' ignored\n", modname, param);
3247 return 0; 3255 return 0;