diff options
author | attilio <attilio@FreeBSD.org> | 2009-06-25 20:59:37 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2009-06-25 20:59:37 +0000 |
commit | b5fb3d044ba3871b3ea31f6b6f1586de46c3d2b3 (patch) | |
tree | 2f657c3284423777a3c940226dc585a9d867603a /sys/dev/hwpmc/hwpmc_mod.c | |
parent | 26f635f51fa012eb580d6a06f40c81be3eeb2e57 (diff) | |
download | FreeBSD-src-b5fb3d044ba3871b3ea31f6b6f1586de46c3d2b3.zip FreeBSD-src-b5fb3d044ba3871b3ea31f6b6f1586de46c3d2b3.tar.gz |
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
Diffstat (limited to 'sys/dev/hwpmc/hwpmc_mod.c')
-rw-r--r-- | sys/dev/hwpmc/hwpmc_mod.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index c239a69..482db0e 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -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, void *syscall_args) 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, void *syscall_args) * 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, void *syscall_args) 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); |