sched/core: Use kfree_rcu() in do_set_cpus_allowed()
authorWaiman Long <longman@redhat.com>
Sat, 31 Dec 2022 04:11:20 +0000 (23:11 -0500)
committerIngo Molnar <mingo@kernel.org>
Mon, 9 Jan 2023 10:43:23 +0000 (11:43 +0100)
commit9a5418bc48babb313d2a62df29ebe21ce8c06c59
tree98446ca9be18345ffe01388cd7c5e983abe35aed
parent87ca4f9efbd7cc649ff43b87970888f2812945b8
sched/core: Use kfree_rcu() in do_set_cpus_allowed()

Commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
do_set_cpus_allowed()") may call kfree() if user_cpus_ptr was previously
set. Unfortunately, some of the callers of do_set_cpus_allowed()
may have pi_lock held when calling it. So the following splats may be
printed especially when running with a PREEMPT_RT kernel:

   WARNING: possible circular locking dependency detected
   BUG: sleeping function called from invalid context

To avoid these problems, kfree_rcu() is used instead. An internal
cpumask_rcuhead union is created for the sole purpose of facilitating
the use of kfree_rcu() to free the cpumask.

Since user_cpus_ptr is not being used in non-SMP configs, the newly
introduced alloc_user_cpus_ptr() helper will return NULL in this case
and sched_setaffinity() is modified to handle this special case.

Fixes: 851a723e45d1 ("sched: Always clear user_cpus_ptr in do_set_cpus_allowed()")
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20221231041120.440785-3-longman@redhat.com
kernel/sched/core.c