Page MenuHomeFreeBSD

Rename tdq_ipipending and clear it in sched_switch().
ClosedPublic

Authored by markj on Dec 11 2019, 2:10 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, May 2, 8:59 AM
Unknown Object (File)
Mar 7 2024, 12:23 PM
Unknown Object (File)
Mar 7 2024, 12:00 PM
Unknown Object (File)
Jan 9 2024, 11:34 PM
Unknown Object (File)
Jan 9 2024, 11:34 PM
Unknown Object (File)
Jan 9 2024, 11:34 PM
Unknown Object (File)
Jan 9 2024, 11:14 PM
Unknown Object (File)
Dec 23 2023, 11:06 PM
Subscribers

Details

Summary

Otherwise sched_preempt() is too fragile. tdq_notify() only raises an
IPI after it adds a new thread to the remote CPU's run queues, so any
switch on the remote CPU once the tdq is unlocked will satisfy the
preemption request.

This fixes a subtle regression from r355311. Suppose a thread is
interrupted by IPI_PREEMPT after decrementing critnest to 0 and before
handling td_owepreempt != 0. sched_preempt() will acquire the thread
lock, and thread_lock() may call spinlock_exit() in its slow path, which
can trigger td_owepreempt handling and cause a switch. The interrupted
thread may then resume on a different CPU, leaving tdq_ipipending set
and thus preventing any further preemptions.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

In fact, this was a problem even before r355311: bhyve briefly enables interrupts after a vmexit caused by a host interrupt and before calling the ISR. If the vcpu threads are not pinned, one may be preempted during this window and migrate, leaving tdq_ipipending set forever. r355311 apparently just made the problem easier to hit.

This revision is now accepted and ready to land.Dec 11 2019, 8:10 AM