diff options
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r-- | kernel/kmod.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 81c67050c5aa..d38b2dab99a7 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -45,8 +45,6 @@ extern int max_threads; -static struct workqueue_struct *khelper_wq; - #define CAP_BSET (void *)1 #define CAP_PI (void *)2 @@ -225,7 +223,7 @@ static int call_usermodehelper_exec_async(void *data) spin_unlock_irq(¤t->sighand->siglock); /* - * Our parent is khelper which runs with elevated scheduling + * Our parent (unbound workqueue) runs with elevated scheduling * priority. Avoid propagating that into the userspace child. */ set_user_nice(current, 0); @@ -268,9 +266,10 @@ out: } /* - * Handles UMH_WAIT_PROC. Our parent khelper can't wait for usermodehelper - * completion without blocking every other pending requests. That's why - * we use a kernel thread dedicated for that purpose. + * Handles UMH_WAIT_PROC. Our parent (unbound workqueue) might not be able to + * run enough instances to handle usermodehelper completions without blocking + * some other pending requests. That's why we use a kernel thread dedicated for + * that purpose. */ static int call_usermodehelper_exec_sync(void *data) { @@ -312,14 +311,15 @@ static int call_usermodehelper_exec_sync(void *data) /* * This function doesn't strictly needs to be called asynchronously. But we * need to create the usermodehelper kernel threads from a task that is affine - * to all CPUs (or nohz housekeeping ones) such that they inherit a widest - * affinity irrespective of call_usermodehelper() callers with possibly reduced - * affinity (eg: per-cpu workqueues). We don't want usermodehelper targets to - * contend any busy CPU. - * Khelper provides such wide affinity. + * to an optimized set of CPUs (or nohz housekeeping ones) such that they + * inherit a widest affinity irrespective of call_usermodehelper() callers with + * possibly reduced affinity (eg: per-cpu workqueues). We don't want + * usermodehelper targets to contend a busy CPU. + * + * Unbound workqueues provide such wide affinity. * - * Besides, khelper provides the privilege level that caller might not have to - * perform the usermodehelper request. + * Besides, workqueues provide the privilege level that caller might not have + * to perform the usermodehelper request. * */ static void call_usermodehelper_exec_work(struct work_struct *work) @@ -549,8 +549,8 @@ EXPORT_SYMBOL(call_usermodehelper_setup); * from interrupt context. * * Runs a user-space application. The application is started - * asynchronously if wait is not set, and runs as a child of khelper. - * (ie. it runs with full root capabilities and wide affinity). + * asynchronously if wait is not set, and runs as a child of system workqueues. + * (ie. it runs with full root capabilities and optimized affinity). */ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) { @@ -562,7 +562,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) return -EINVAL; } helper_lock(); - if (!khelper_wq || usermodehelper_disabled) { + if (usermodehelper_disabled) { retval = -EBUSY; goto out; } @@ -574,7 +574,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) sub_info->complete = (wait == UMH_NO_WAIT) ? NULL : &done; sub_info->wait = wait; - queue_work(khelper_wq, &sub_info->work); + queue_work(system_unbound_wq, &sub_info->work); if (wait == UMH_NO_WAIT) /* task has freed sub_info */ goto unlock; @@ -704,9 +704,3 @@ struct ctl_table usermodehelper_table[] = { }, { } }; - -void __init usermodehelper_init(void) -{ - khelper_wq = create_singlethread_workqueue("khelper"); - BUG_ON(!khelper_wq); -} |