git: c2d27b0ec700 - main - sched_4bsd: Fix a racy thread state modification

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Sat, 24 Sep 2022 00:16:29 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=c2d27b0ec7000d28b4f31148005ccfe371f47db3

commit c2d27b0ec7000d28b4f31148005ccfe371f47db3
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-09-23 23:41:30 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-09-24 00:09:06 +0000

    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
---
 sys/kern/sched_4bsd.c | 7 ++++---
 1 file 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 */