Skip to content

Commit 63a4818

Browse files
compudjIngo Molnar
authored andcommitted
smp/scf: Evaluate local cond_func() before IPI side-effects
In smp_call_function_many_cond(), the local cond_func() is evaluated after triggering the remote CPU IPIs. If cond_func() depends on loading shared state updated by other CPU's IPI handlers func(), then triggering execution of remote CPUs IPI before evaluating cond_func() may have unexpected consequences. One example scenario is evaluating a jiffies delay in cond_func(), which is updated by func() in the IPI handlers. This situation can prevent execution of periodic cleanup code on the local CPU. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Rik van Riel <riel@surriel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20241203163558.3455535-1-mathieu.desnoyers@efficios.com
1 parent d387ceb commit 63a4818

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

kernel/smp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ static void smp_call_function_many_cond(const struct cpumask *mask,
815815
WARN_ON_ONCE(!in_task());
816816

817817
/* Check if we need local execution. */
818-
if ((scf_flags & SCF_RUN_LOCAL) && cpumask_test_cpu(this_cpu, mask))
818+
if ((scf_flags & SCF_RUN_LOCAL) && cpumask_test_cpu(this_cpu, mask) &&
819+
(!cond_func || cond_func(this_cpu, info)))
819820
run_local = true;
820821

821822
/* Check if we need remote execution, i.e., any CPU excluding this one. */
@@ -868,7 +869,7 @@ static void smp_call_function_many_cond(const struct cpumask *mask,
868869
send_call_function_ipi_mask(cfd->cpumask_ipi);
869870
}
870871

871-
if (run_local && (!cond_func || cond_func(this_cpu, info))) {
872+
if (run_local) {
872873
unsigned long flags;
873874

874875
local_irq_save(flags);

0 commit comments

Comments
 (0)