Author: attilio Date: Thu Jun 25 20:59:37 2009 New Revision: 195005 URL: http://svn.freebsd.org/changeset/base/195005
Log: Fix a LOR between pmc_sx and proctree/allproc when creating a new thread for the pmclog. Reported by: Ryan Stone <rstone at sandvine dot com> Tested by: Ryan Stone <rstone at sandvine dot com> Sponsored by: Sandvine Incorporated Modified: head/sys/dev/hwpmc/hwpmc_logging.c head/sys/dev/hwpmc/hwpmc_mod.c Modified: head/sys/dev/hwpmc/hwpmc_logging.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_logging.c Thu Jun 25 20:57:53 2009 (r195004) +++ head/sys/dev/hwpmc/hwpmc_logging.c Thu Jun 25 20:59:37 2009 (r195005) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/mutex.h> #include <sys/pmc.h> +#include <sys/pmckern.h> #include <sys/pmclog.h> #include <sys/proc.h> #include <sys/signalvar.h> @@ -552,6 +553,12 @@ pmclog_configure_log(struct pmc_mdep *md int error; struct proc *p; + /* + * As long as it is possible to get a LOR between pmc_sx lock and + * proctree/allproc sx locks used for adding a new process, assure + * the former is not held here. + */ + sx_assert(&pmc_sx, SA_UNLOCKED); PMCDBG(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); p = po->po_owner; Modified: head/sys/dev/hwpmc/hwpmc_mod.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_mod.c Thu Jun 25 20:57:53 2009 (r195004) +++ head/sys/dev/hwpmc/hwpmc_mod.c Thu Jun 25 20:59:37 2009 (r195005) @@ -2663,7 +2663,7 @@ static const char *pmc_op_to_name[] = { static int pmc_syscall_handler(struct thread *td, void *syscall_args) { - int error, is_sx_downgraded, op; + int error, is_sx_downgraded, is_sx_locked, op; struct pmc_syscall_args *c; void *arg; @@ -2672,6 +2672,7 @@ pmc_syscall_handler(struct thread *td, v DROP_GIANT(); is_sx_downgraded = 0; + is_sx_locked = 1; c = (struct pmc_syscall_args *) syscall_args; @@ -2720,9 +2721,11 @@ pmc_syscall_handler(struct thread *td, v * a log file configured, flush its buffers and * de-configure it. */ - if (cl.pm_logfd >= 0) + if (cl.pm_logfd >= 0) { + sx_xunlock(&pmc_sx); + is_sx_locked = 0; error = pmclog_configure_log(md, po, cl.pm_logfd); - else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { + } else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { pmclog_process_closelog(po); error = pmclog_flush(po); if (error == 0) { @@ -3772,10 +3775,12 @@ pmc_syscall_handler(struct thread *td, v break; } - if (is_sx_downgraded) - sx_sunlock(&pmc_sx); - else - sx_xunlock(&pmc_sx); + if (is_sx_locked != 0) { + if (is_sx_downgraded) + sx_sunlock(&pmc_sx); + else + sx_xunlock(&pmc_sx); + } if (error) atomic_add_int(&pmc_stats.pm_syscall_errors, 1); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"