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)
Oct 21 2024, 5:58 PM
Unknown Object (File)
Oct 2 2024, 10:17 AM
Unknown Object (File)
Sep 20 2024, 9:44 AM
Unknown Object (File)
Sep 20 2024, 9:38 AM
Unknown Object (File)
Sep 20 2024, 9:38 AM
Unknown Object (File)
Sep 20 2024, 4:29 AM
Unknown Object (File)
Sep 18 2024, 10:31 PM
Unknown Object (File)
Sep 5 2024, 8:19 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