diff --git a/include/linux/kthread.h b/include/linux/kthread.h index c1961761311dbfd5968d6ed64ea91ca3c7d25b0e..33e1f0052940beadb7d161eef9217c453aac8813 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -66,6 +66,7 @@ void kthread_parkme(void); int kthreadd(void *unused); extern struct task_struct *kthreadd_task; extern int tsk_fork_get_node(struct task_struct *tsk); +extern void set_kthreadd_affinity(void); /* * Simple work processor based on kthread. diff --git a/kernel/kthread.c b/kernel/kthread.c index 087d18d771b537972b4bacf8c5528a3c40fc91e5..7973996e061fbffa77134f65c4c3fb6c0d0f9c6f 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -156,6 +156,15 @@ void *kthread_data(struct task_struct *task) return to_kthread(task)->data; } +/* + * Set the affinity of the calling task to be the same + * as the kthreadd affinities. + */ +void set_kthreadd_affinity(void) +{ + set_cpus_allowed_ptr(current, &kthreadd_task->cpus_allowed); +} + /** * kthread_probe_data - speculative version of kthread_data() * @task: possible kthread task in question diff --git a/kernel/umh.c b/kernel/umh.c index 0baa672e023cb86e84ad11a34e6cf22cb82e2e6e..173d55579601b3c8a0f76a47a75ccd69271c8114 100644 --- a/kernel/umh.c +++ b/kernel/umh.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -72,6 +73,15 @@ static int call_usermodehelper_exec_async(void *data) flush_signal_handlers(current, 1); spin_unlock_irq(¤t->sighand->siglock); + /* + * Kthreadd can be restricted to a set of processors if the user wants + * to protect other processors from OS latencies. If that has happened + * then we do not want to disturb the other processors here either so we + * start the usermode helper threads only on the processors allowed for + * kthreadd. + */ + set_kthreadd_affinity(); + /* * Our parent (unbound workqueue) runs with elevated scheduling * priority. Avoid propagating that into the userspace child.