summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2012-03-27 14:02:22 +0000
committerfabient <fabient@FreeBSD.org>2012-03-27 14:02:22 +0000
commit961cc7f6b46bf3162f967f3b4ff8a1d0dce295b1 (patch)
treed6cedc28ae8893c3b53577cdd6e81e0c3d98d172 /sys/dev
parent4d0abc074bb260da29534b6db70f63da7dd99f5f (diff)
downloadFreeBSD-src-961cc7f6b46bf3162f967f3b4ff8a1d0dce295b1.zip
FreeBSD-src-961cc7f6b46bf3162f967f3b4ff8a1d0dce295b1.tar.gz
Fix random deadlock on pmcstat exit:
- Exit the thread when soft shutdown is requested - Wakeup owner thread. Reproduced/tested by looping pmcstat measurement: pmcstat -S instructions -O/tmp/test ls MFC after: 1 week
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index 5f5cd90..79170ed 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -285,6 +285,7 @@ pmclog_loop(void *arg)
if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) {
mtx_unlock_spin(&po->po_mtx);
+ /* No more buffers and shutdown required. */
if (po->po_flags & PMC_PO_SHUTDOWN) {
mtx_unlock(&pmc_kthread_mtx);
/*
@@ -293,6 +294,7 @@ pmclog_loop(void *arg)
*/
fo_close(po->po_file, curthread);
mtx_lock(&pmc_kthread_mtx);
+ break;
}
(void) msleep(po, &pmc_kthread_mtx, PWAIT,
@@ -355,6 +357,7 @@ pmclog_loop(void *arg)
lb = NULL;
}
+ wakeup_one(po->po_kthread);
po->po_kthread = NULL;
mtx_unlock(&pmc_kthread_mtx);
@@ -653,8 +656,7 @@ pmclog_deconfigure_log(struct pmc_owner *po)
("[pmclog,%d] po=%p no log file", __LINE__, po));
/* stop the kthread, this will reset the 'OWNS_LOGFILE' flag */
- if (po->po_kthread)
- pmclog_stop_kthread(po);
+ pmclog_stop_kthread(po);
KASSERT(po->po_kthread == NULL,
("[pmclog,%d] po=%p kthread not stopped", __LINE__, po));
OpenPOWER on IntegriCloud