From owner-svn-src-all@FreeBSD.ORG Tue Nov 24 19:26:54 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 35CE8106566B; Tue, 24 Nov 2009 19:26:54 +0000 (UTC) (envelope-from fabient@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1A3278FC13; Tue, 24 Nov 2009 19:26:54 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAOJQrqE027488; Tue, 24 Nov 2009 19:26:53 GMT (envelope-from fabient@svn.freebsd.org) Received: (from fabient@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAOJQr0i027487; Tue, 24 Nov 2009 19:26:53 GMT (envelope-from fabient@svn.freebsd.org) Message-Id: <200911241926.nAOJQr0i027487@svn.freebsd.org> From: Fabien Thomas Date: Tue, 24 Nov 2009 19:26:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199763 - head/sys/dev/hwpmc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Nov 2009 19:26:54 -0000 Author: fabient Date: Tue Nov 24 19:26:53 2009 New Revision: 199763 URL: http://svn.freebsd.org/changeset/base/199763 Log: - fix a LOR between process lock and pmc thread mutex - fix a system deadlock on process exit when the sample buffer is full (pmclog_loop blocked in fo_write) and pmcstat exit. Reviewed by: jkoshy MFC after: 3 weeks Modified: head/sys/dev/hwpmc/hwpmc_logging.c Modified: head/sys/dev/hwpmc/hwpmc_logging.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_logging.c Tue Nov 24 18:34:47 2009 (r199762) +++ head/sys/dev/hwpmc/hwpmc_logging.c Tue Nov 24 19:26:53 2009 (r199763) @@ -240,6 +240,7 @@ pmclog_loop(void *arg) int error; struct pmc_owner *po; struct pmclog_buffer *lb; + struct proc *p; struct ucred *ownercred; struct ucred *mycred; struct thread *td; @@ -248,12 +249,13 @@ pmclog_loop(void *arg) size_t nbytes; po = (struct pmc_owner *) arg; + p = po->po_owner; td = curthread; mycred = td->td_ucred; - PROC_LOCK(po->po_owner); - ownercred = crhold(po->po_owner->p_ucred); - PROC_UNLOCK(po->po_owner); + PROC_LOCK(p); + ownercred = crhold(p->p_ucred); + PROC_UNLOCK(p); PMCDBG(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread); KASSERT(po->po_kthread == curthread->td_proc, @@ -324,16 +326,16 @@ pmclog_loop(void *arg) error = fo_write(po->po_file, &auio, ownercred, 0, td); td->td_ucred = mycred; - mtx_lock(&pmc_kthread_mtx); - if (error) { /* XXX some errors are recoverable */ /* XXX also check for SIGPIPE if a socket */ /* send a SIGIO to the owner and exit */ - PROC_LOCK(po->po_owner); - psignal(po->po_owner, SIGIO); - PROC_UNLOCK(po->po_owner); + PROC_LOCK(p); + psignal(p, SIGIO); + PROC_UNLOCK(p); + + mtx_lock(&pmc_kthread_mtx); po->po_error = error; /* save for flush log */ @@ -342,6 +344,8 @@ pmclog_loop(void *arg) break; } + mtx_lock(&pmc_kthread_mtx); + /* put the used buffer back into the global pool */ PMCLOG_INIT_BUFFER_DESCRIPTOR(lb); @@ -525,15 +529,20 @@ static void pmclog_stop_kthread(struct pmc_owner *po) { /* - * Unset flag, wakeup the helper thread, + * Close the file to force the thread out of fo_write, + * unset flag, wakeup the helper thread, * wait for it to exit */ - mtx_assert(&pmc_kthread_mtx, MA_OWNED); + if (po->po_file != NULL) + fo_close(po->po_file, curthread); + + mtx_lock(&pmc_kthread_mtx); po->po_flags &= ~PMC_PO_OWNS_LOGFILE; wakeup_one(po); if (po->po_kthread) msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0); + mtx_unlock(&pmc_kthread_mtx); } /* @@ -602,10 +611,8 @@ pmclog_configure_log(struct pmc_mdep *md error: /* shutdown the thread */ - mtx_lock(&pmc_kthread_mtx); if (po->po_kthread) pmclog_stop_kthread(po); - mtx_unlock(&pmc_kthread_mtx); KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not " "stopped", __LINE__, po)); @@ -641,10 +648,8 @@ pmclog_deconfigure_log(struct pmc_owner ("[pmclog,%d] po=%p no log file", __LINE__, po)); /* stop the kthread, this will reset the 'OWNS_LOGFILE' flag */ - mtx_lock(&pmc_kthread_mtx); if (po->po_kthread) pmclog_stop_kthread(po); - mtx_unlock(&pmc_kthread_mtx); KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not stopped", __LINE__, po));