fix a thread preemption regression in schedulers introduced in r270423
Commit r270423 fixed a regression in sched_yield() that was introduced in earlier changes. Unfortunately, at the same time it introduced an new regression. The problem is that SWT_RELINQUISH (6), like all other SWT_* constants and unlike SW_* flags, is not a bit flag. So, (flags & SWT_RELINQUISH) is true in cases where that was not really indended, for example, with SWT_OWEPREEMPT (2) and SWT_REMOTEPREEMPT (11). A straight forward fix would be to use (flags & SW_TYPE_MASK) == SWT_RELINQUISH, but my impression is that the switch types are designed mostly for gathering statistics, not for influencing scheduling decisions. So, I decided that it would be better to check for SW_PREEMPT flag instead. That's also the same flag that was checked before r239157. I double-checked how that flag is used and I am confident that the flag is set only in the places where we really have the preemption: - critical_exit + td_owepreempt - sched_preempt in the ULE scheduler - sched_preempt in the 4BSD scheduler Reviewed by: kib, mav MFC after: 4 days Sponsored by: Panzura Differential Revision: https://reviews.freebsd.org/D9230
This commit is contained in:
parent
1c07d69bc2
commit
ad9dadc437
@ -968,8 +968,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
|
||||
sched_load_rem();
|
||||
|
||||
td->td_lastcpu = td->td_oncpu;
|
||||
preempted = !((td->td_flags & TDF_SLICEEND) ||
|
||||
(flags & SWT_RELINQUISH));
|
||||
preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
|
||||
(flags & SW_PREEMPT) != 0;
|
||||
td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
|
||||
td->td_owepreempt = 0;
|
||||
td->td_oncpu = NOCPU;
|
||||
|
@ -1898,8 +1898,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
|
||||
ts->ts_rltick = ticks;
|
||||
td->td_lastcpu = td->td_oncpu;
|
||||
td->td_oncpu = NOCPU;
|
||||
preempted = !((td->td_flags & TDF_SLICEEND) ||
|
||||
(flags & SWT_RELINQUISH));
|
||||
preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
|
||||
(flags & SW_PREEMPT) != 0;
|
||||
td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
|
||||
td->td_owepreempt = 0;
|
||||
if (!TD_IS_IDLETHREAD(td))
|
||||
|
Loading…
Reference in New Issue
Block a user