diff options
author | fabient <fabient@FreeBSD.org> | 2012-03-27 14:02:22 +0000 |
---|---|---|
committer | fabient <fabient@FreeBSD.org> | 2012-03-27 14:02:22 +0000 |
commit | 961cc7f6b46bf3162f967f3b4ff8a1d0dce295b1 (patch) | |
tree | d6cedc28ae8893c3b53577cdd6e81e0c3d98d172 /sys/dev/hwpmc/hwpmc_logging.c | |
parent | 4d0abc074bb260da29534b6db70f63da7dd99f5f (diff) | |
download | FreeBSD-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/hwpmc/hwpmc_logging.c')
-rw-r--r-- | sys/dev/hwpmc/hwpmc_logging.c | 6 |
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)); |