aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/sched_ule.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2022-07-18 19:50:45 +0000
committerMark Johnston <markj@FreeBSD.org>2022-07-18 19:52:27 +0000
commitbd980ca847b76439bd27a4144cf0dd69d48b33af (patch)
tree2d1414f82da6659a63c43c19bbc06d53c71f44dd /sys/kern/sched_ule.c
parentf5ad538d90673b0247b571deb38825bc6822cf20 (diff)
downloadsrc-bd980ca847b76439bd27a4144cf0dd69d48b33af.tar.gz
src-bd980ca847b76439bd27a4144cf0dd69d48b33af.zip
sched_ule: Ensure we hold the thread lock when modifying td_flags
The load balancer may force a running thread to reschedule and pick a new CPU. To do this it sets some flags in the thread running on a loaded CPU. But the code assumed that a running thread's lock is the same as that of the corresponding runqueue, and there are small windows where this is not true. In this case, we can end up with non-atomic modifications to td_flags. Since this load balancing is best-effort, simply give up if the thread's lock doesn't match; in this case the thread is about to enter the scheduler anyway. Reviewed by: kib Reported by: glebius Fixes: e745d729be60 ("sched_ule(4): Improve long-term load balancer.") MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D35821
Diffstat (limited to 'sys/kern/sched_ule.c')
-rw-r--r--sys/kern/sched_ule.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 138cb13e0fbe..0f5a73767408 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -871,7 +871,8 @@ sched_balance_group(struct cpu_group *cg)
*/
TDQ_LOCK(tdq);
td = tdq->tdq_curthread;
- if ((td->td_flags & TDF_IDLETD) == 0 &&
+ if (td->td_lock == TDQ_LOCKPTR(tdq) &&
+ (td->td_flags & TDF_IDLETD) == 0 &&
THREAD_CAN_MIGRATE(td)) {
td->td_flags |= TDF_NEEDRESCHED | TDF_PICKCPU;
if (high != curcpu)