Index: sys/kern/sched_ule.c =================================================================== --- sys/kern/sched_ule.c +++ sys/kern/sched_ule.c @@ -2383,10 +2383,18 @@ SDT_PROBE2(sched, , , surrender, td, td->td_proc); + /* + * Avoid switching while tdq_ipipending is set. thread_lock() may + * trigger a switch if the initial attempt to acquire the lock fails and + * the interrupted thread was handling td_owepreempt. + */ + critical_enter(); thread_lock(td); tdq = TDQ_SELF(); TDQ_LOCK_ASSERT(tdq, MA_OWNED); + KASSERT(tdq->tdq_ipipending, ("no pending IPI")); tdq->tdq_ipipending = 0; + td->td_critnest--; if (td->td_priority > tdq->tdq_lowpri) { int flags;