From beaabf6cd8d215b34e13b596af794e10b6b7dd1d Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Tue, 10 Apr 2018 09:24:57 +0000 Subject: Do not call logwakeup(), ending in wakeup_n(), while holding a mutex. Prevents a lock ordering issue between SCHED_LOCK() and printf(9)'s mutex. While here protect all kprintf() calls ending on the console with the mutex. ok kettenis@, visa@ --- sys/kern/subr_prf.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index c75e2a88769..afa49ef332d 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prf.c,v 1.94 2018/03/20 15:45:32 mpi Exp $ */ +/* $OpenBSD: subr_prf.c,v 1.95 2018/04/10 09:24:56 mpi Exp $ */ /* $NetBSD: subr_prf.c,v 1.45 1997/10/24 18:14:25 chuck Exp $ */ /*- @@ -264,7 +264,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 +306,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 +506,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 +530,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); } @@ -687,6 +690,9 @@ kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap) 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; -- cgit v1.2.3