Diff below avoids a lock ordering issue between the SCHED_LOCK() and printf(9)'s mutex. This problem has been reported multiple times in drm(4) code where debug printfs are placed between sleep_setup() and sleep_finish().
The problem is easily fixed. logwakeup() must not be called while holding the mutex. This function can end up in wakeup_n() which will grab the SCHED_LOCK(). While here ensure that the mutex is always when TOCONS is specified. This was not the case in the error path of log(9) and addlog(9). Ok? Index: kern/subr_prf.c =================================================================== RCS file: /cvs/src/sys/kern/subr_prf.c,v retrieving revision 1.94 diff -u -p -r1.94 subr_prf.c --- kern/subr_prf.c 20 Mar 2018 15:45:32 -0000 1.94 +++ kern/subr_prf.c 9 Apr 2018 11:35:11 -0000 @@ -89,8 +89,7 @@ int kprintf(const char *, int, void *, char *, va_list); void kputchar(int, int, struct tty *); -struct mutex kprintf_mutex = - MUTEX_INITIALIZER_FLAGS(IPL_HIGH, "kprintf", MTX_NOWITNESS); +struct mutex kprintf_mutex = MUTEX_INITIALIZER(IPL_HIGH); /* * globals @@ -264,7 +263,9 @@ log(int level, const char *fmt, ...) splx(s); if (!log_open) { va_start(ap, fmt); + mtx_enter(&kprintf_mutex); kprintf(fmt, TOCONS, NULL, NULL, ap); + mtx_leave(&kprintf_mutex); va_end(ap); } logwakeup(); /* wake up anyone waiting for log msgs */ @@ -304,7 +305,9 @@ addlog(const char *fmt, ...) splx(s); if (!log_open) { va_start(ap, fmt); + mtx_enter(&kprintf_mutex); kprintf(fmt, TOCONS, NULL, NULL, ap); + mtx_leave(&kprintf_mutex); va_end(ap); } logwakeup(); @@ -502,15 +505,15 @@ printf(const char *fmt, ...) va_list ap; int retval; - mtx_enter(&kprintf_mutex); va_start(ap, fmt); + mtx_enter(&kprintf_mutex); retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); + mtx_leave(&kprintf_mutex); va_end(ap); if (!panicstr) logwakeup(); - mtx_leave(&kprintf_mutex); return(retval); } @@ -526,12 +529,11 @@ vprintf(const char *fmt, va_list ap) int retval; mtx_enter(&kprintf_mutex); - retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); + mtx_leave(&kprintf_mutex); if (!panicstr) logwakeup(); - mtx_leave(&kprintf_mutex); return (retval); } @@ -686,6 +688,9 @@ kprintf(const char *fmt0, int oflags, vo char *xdigs = NULL; /* digits for [xX] conversion */ char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */ char *tailp = NULL; /* tail pointer for snprintf */ + + if (oflags & TOCONS) + MUTEX_ASSERT_LOCKED(&kprintf_mutex); if ((oflags & TOBUFONLY) && (vp != NULL)) tailp = *(char **)vp;