diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index a9c32daeb9d88376a4e7ce79e7de13534c95b2ea..4993c00824a308338fd540372b0896171a7fe3a3 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -83,4 +83,5 @@ extern int sysctl_schedstats(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +extern int sysctl_umh_affinity; #endif /* _LINUX_SCHED_SYSCTL_H */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 201cb993869bded304d24a58eb5aecbe57ae712b..2955298d0dd4349df7e83fad9f9174a3bb3a2fda 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1240,6 +1240,15 @@ static struct ctl_table kern_table[] = { .extra2 = &one, }, #endif + { + .procname = "usermodhelper_affinity", + .data = &sysctl_umh_affinity, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, { } }; diff --git a/kernel/umh.c b/kernel/umh.c index 173d55579601b3c8a0f76a47a75ccd69271c8114..7de3b21854ab7b667e9ad913807941c4c7591795 100644 --- a/kernel/umh.c +++ b/kernel/umh.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -39,6 +40,8 @@ static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; static DEFINE_SPINLOCK(umh_sysctl_lock); static DECLARE_RWSEM(umhelper_sem); +int __read_mostly sysctl_umh_affinity; + static void call_usermodehelper_freeinfo(struct subprocess_info *info) { if (info->cleanup) @@ -80,7 +83,10 @@ static int call_usermodehelper_exec_async(void *data) * start the usermode helper threads only on the processors allowed for * kthreadd. */ - set_kthreadd_affinity(); + if (sysctl_umh_affinity) + set_kthreadd_affinity(); + else + set_cpus_allowed_ptr(current, cpu_all_mask); /* * Our parent (unbound workqueue) runs with elevated scheduling