]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
When sleeping waiting for the profiling stop, always set P_STOPPROF
authorkib <kib@FreeBSD.org>
Mon, 10 Nov 2014 14:11:17 +0000 (14:11 +0000)
committerkib <kib@FreeBSD.org>
Mon, 10 Nov 2014 14:11:17 +0000 (14:11 +0000)
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

sys/kern/kern_clock.c
sys/kern/subr_prof.c

index 3d232cf744c5a8b85cc1395d66a5def4ae1e0d07..79a294d37e3d647a96cef1c7255a92a980d6e4bc 100644 (file)
@@ -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;
index efd66b274ea586517192a2776d2edefd504790cd..cedfc1b3d1db328727981c3dbc16d383a723b917 100644 (file)
@@ -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;
                }
        }