svn commit: r195005 - head/sys/dev/hwpmc

Attilio Rao attilio at FreeBSD.org
Thu Jun 25 20:59:38 UTC 2009


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);


More information about the svn-src-head mailing list