Skip to content

Commit 6343402

Browse files
liupingfanpaulmckrcu
authored andcommitted
rcu: Synchronize ->qsmaskinitnext in rcu_boost_kthread_setaffinity()
Once either rcutree_online_cpu() or rcutree_dead_cpu() is invoked concurrently, the following rcu_boost_kthread_setaffinity() race can occur: CPU 1 CPU2 mask = rcu_rnp_online_cpus(rnp); ... mask = rcu_rnp_online_cpus(rnp); ... set_cpus_allowed_ptr(t, cm); set_cpus_allowed_ptr(t, cm); This results in CPU2's update being overwritten by that of CPU1, and thus the possibility of ->boost_kthread_task continuing to run on a to-be-offlined CPU. This commit therefore eliminates this race by relying on the pre-existing acquisition of ->boost_kthread_mutex to serialize the full process of changing the affinity of ->boost_kthread_task. Signed-off-by: Pingfan Liu <kernelfans@gmail.com> Cc: David Woodhouse <dwmw@amazon.co.uk> Cc: Frederic Weisbecker <frederic@kernel.org> Cc: Neeraj Upadhyay <quic_neeraju@quicinc.com> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Lai Jiangshan <jiangshanlai@gmail.com> Cc: Joel Fernandes <joel@joelfernandes.org> Cc: "Jason A. Donenfeld" <Jason@zx2c4.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
1 parent d6fd907 commit 6343402

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

kernel/rcu/tree_plugin.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,11 +1221,13 @@ static void rcu_spawn_one_boost_kthread(struct rcu_node *rnp)
12211221
* We don't include outgoingcpu in the affinity set, use -1 if there is
12221222
* no outgoing CPU. If there are no CPUs left in the affinity set,
12231223
* this function allows the kthread to execute on any CPU.
1224+
*
1225+
* Any future concurrent calls are serialized via ->boost_kthread_mutex.
12241226
*/
12251227
static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
12261228
{
12271229
struct task_struct *t = rnp->boost_kthread_task;
1228-
unsigned long mask = rcu_rnp_online_cpus(rnp);
1230+
unsigned long mask;
12291231
cpumask_var_t cm;
12301232
int cpu;
12311233

@@ -1234,6 +1236,7 @@ static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
12341236
if (!zalloc_cpumask_var(&cm, GFP_KERNEL))
12351237
return;
12361238
mutex_lock(&rnp->boost_kthread_mutex);
1239+
mask = rcu_rnp_online_cpus(rnp);
12371240
for_each_leaf_node_possible_cpu(rnp, cpu)
12381241
if ((mask & leaf_node_cpu_bit(rnp, cpu)) &&
12391242
cpu != outgoingcpu)

0 commit comments

Comments
 (0)