diff options
author | kib <kib@FreeBSD.org> | 2014-11-10 14:11:17 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-11-10 14:11:17 +0000 |
commit | 4c07fb2889f7bfe947bca15c8ea892191db972a3 (patch) | |
tree | 83e807a8dbd06c3d296affa86ff227566901e745 | |
parent | 4a7f34f96cefed3fd776294cb84d5feb7869a980 (diff) | |
download | FreeBSD-src-4c07fb2889f7bfe947bca15c8ea892191db972a3.zip FreeBSD-src-4c07fb2889f7bfe947bca15c8ea892191db972a3.tar.gz |
When sleeping waiting for the profiling stop, always set P_STOPPROF
before dropping process lock. Clear P_STOPPROF when doing wakeup.
Both issues caused thread to hang in stopprofclock() "stopprof" sleep.
Reported and tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
-rw-r--r-- | sys/kern/kern_clock.c | 6 | ||||
-rw-r--r-- | sys/kern/subr_prof.c | 1 |
2 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 3d232cf..79a294d 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -668,11 +668,11 @@ stopprofclock(p) PROC_LOCK_ASSERT(p, MA_OWNED); if (p->p_flag & P_PROFIL) { if (p->p_profthreads != 0) { - p->p_flag |= P_STOPPROF; - while (p->p_profthreads != 0) + while (p->p_profthreads != 0) { + p->p_flag |= P_STOPPROF; msleep(&p->p_profthreads, &p->p_mtx, PPAUSE, "stopprof", 0); - p->p_flag &= ~P_STOPPROF; + } } if ((p->p_flag & P_PROFIL) == 0) return; diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index efd66b2..cedfc1b 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -533,6 +533,7 @@ out: if (--p->p_profthreads == 0) { if (p->p_flag & P_STOPPROF) { wakeup(&p->p_profthreads); + p->p_flag &= ~P_STOPPROF; stop = 0; } } |