HomeFreeBSD

ktrcsw(): should not be called when the thread is owning interlock or on sleepq

Description

ktrcsw(): should not be called when the thread is owning interlock or on sleepq

The issue is that for ktrcsw() we lock the ktrace_mtx mutex while owning
the interlock from a subsystem that called msleep(). In particular, the
VM subsystem might call msleep() if page allocation failed. This
establishes order VM locks (e.g. domain free queue lock) -> ktrace_mtx.
Calling free() while owning ktrace_mtx gives the reverse order.

Worse, msleep_spin_sbt() call s ktrcsw() while the thread is put on
sleep queue. Then, since the mutex might be contested, the thread needs
to be put on turnstil, which cannot work.

Move the ktrcsw() call for switch-out after the wakeup, when the thread
does not yet re-obtained any locks. From there, we call a special
version of ktrcsw(), which is passed the actual time when the context
switch occured.

The drawback is that the switch-out record is only written in the
ktrace.out file after the switch-in occurred, but this is probably not
too serious.

Reported and tested by: pho
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54831

Details

Provenance
kibAuthored on Jan 22 2026, 9:46 PM
Reviewer
markj
Differential Revision
D54831: Make ULE and 4BSD coexists
Parents
rGbda802814669: release: Ship firmware from kmods repo on DVD
Branches
Unknown
Tags
Unknown