aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2022-09-23 23:41:30 +0000
committerMark Johnston <markj@FreeBSD.org>2022-09-24 00:09:06 +0000
commitc2d27b0ec7000d28b4f31148005ccfe371f47db3 (patch)
treec6504f3786bef3f3036a8a8e2012a5b627d7d61e
parent7652321b7909002877cabcaee56dc996814070e8 (diff)
downloadsrc-c2d27b0ec7000d28b4f31148005ccfe371f47db3.tar.gz
src-c2d27b0ec7000d28b4f31148005ccfe371f47db3.zip
sched_4bsd: Fix a racy thread state modification
When a thread switching off-CPU is migrating to a remote CPU, sched_switch() may trigger a rescheduling of the thread currently running on that CPU. When doing so, it must ensure that that thread is locked before modifying thread state. If the thread's lock is not the scheduler lock, then the thread is in the process of switching off-CPU and no extra effort is needed, and the initiator does not hold the thread's lock and thus should not modify any thread state. Reported and tested by: Steve Kargl MFC after: 1 week
-rw-r--r--sys/kern/sched_4bsd.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 9d48aa746f6d..8bd697a67e7e 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1282,9 +1282,10 @@ kick_other_cpu(int pri, int cpuid)
}
#endif /* defined(IPI_PREEMPTION) && defined(PREEMPTION) */
- ast_sched_locked(pcpu->pc_curthread, TDA_SCHED);
- ipi_cpu(cpuid, IPI_AST);
- return;
+ if (pcpu->pc_curthread->td_lock == &sched_lock) {
+ ast_sched_locked(pcpu->pc_curthread, TDA_SCHED);
+ ipi_cpu(cpuid, IPI_AST);
+ }
}
#endif /* SMP */