diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index a377001760b9..1dfc237dda37 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -807,7 +807,7 @@ ktr_psig(int sig, sig_t action, const sigset_t *mask, } void -ktr_csw(int out, int user) +ktr_csw(int out, int user, const struct syncobj *syncobj) { lwp_t *l = curlwp; struct proc *p = l->l_proc; @@ -819,9 +819,11 @@ ktr_csw(int out, int user) /* * Don't record context switches resulting from blocking on - * locks; it's too easy to get duff results. + * locks; the results are not useful, and the mutex may be in a + * softint, which would lead us to ktealloc in softint context, + * which is forbidden. */ - if (l->l_syncobj == &mutex_syncobj || l->l_syncobj == &rw_syncobj) + if (syncobj == &mutex_syncobj || syncobj == &rw_syncobj) return; /* diff --git a/sys/kern/kern_sleepq.c b/sys/kern/kern_sleepq.c index c5c86e5a755b..23b5635fd726 100644 --- a/sys/kern/kern_sleepq.c +++ b/sys/kern/kern_sleepq.c @@ -309,6 +309,7 @@ sleepq_block(int timo, bool catch_p) lwp_t *l = curlwp; bool early = false; int biglocks = l->l_biglocks; + struct syncobj *syncobj = l->l_syncobj; KASSERTMSG(l->l_blcnt == 0, "unexpectedly acquired %d biglocks", l->l_blcnt); @@ -321,7 +322,7 @@ sleepq_block(int timo, bool catch_p) */ l->l_biglocks = -1; - ktrcsw(1, 0); + ktrcsw(1, 0, syncobj); /* * If sleeping interruptably, check for pending signals, exits or @@ -408,7 +409,7 @@ sleepq_block(int timo, bool catch_p) } } - ktrcsw(0, 0); + ktrcsw(0, 0, syncobj); KASSERTMSG(l->l_blcnt == 0, "unexpectedly acquired %d biglocks", l->l_blcnt); if (__predict_false(biglocks != 0)) { diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index 0a74223b9dcb..18a0fea03380 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -297,6 +297,8 @@ __END_DECLS #else +struct syncobj; + void ktrinit(void); void ktrderef(struct proc *); void ktradref(struct proc *); @@ -307,7 +309,7 @@ extern int ktrace_on; int ktruser(const char *, void *, size_t, int); bool ktr_point(int); -void ktr_csw(int, int); +void ktr_csw(int, int, const struct syncobj *); void ktr_emul(void); void ktr_geniov(int, enum uio_rw, struct iovec *, size_t, int); void ktr_genio(int, enum uio_rw, const void *, size_t, int); @@ -349,10 +351,10 @@ ktrpoint(int fac) } static __inline void -ktrcsw(int a, int b) +ktrcsw(int a, int b, const struct syncobj *c) { if (__predict_false(ktrace_on)) - ktr_csw(a, b); + ktr_csw(a, b, c); } static __inline void