summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c48
-rw-r--r--sys/sys/pmc.h2
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.c4
3 files changed, 29 insertions, 25 deletions
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index a36a8dc..055433d 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -237,7 +237,7 @@ pmclog_get_buffer(struct pmc_owner *po)
static void
pmclog_loop(void *arg)
{
- int error;
+ int error, last_buffer;
struct pmc_owner *po;
struct pmclog_buffer *lb;
struct proc *p;
@@ -252,6 +252,7 @@ pmclog_loop(void *arg)
p = po->po_owner;
td = curthread;
mycred = td->td_ucred;
+ last_buffer = 0;
PROC_LOCK(p);
ownercred = crhold(p->p_ucred);
@@ -284,27 +285,20 @@ pmclog_loop(void *arg)
if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) {
mtx_unlock_spin(&po->po_mtx);
- /*
- * Wakeup the thread waiting for the
- * PMC_OP_FLUSHLOG request to
- * complete.
- */
- if (po->po_flags & PMC_PO_IN_FLUSH) {
- po->po_flags &= ~PMC_PO_IN_FLUSH;
- wakeup_one(po->po_kthread);
- }
-
(void) msleep(po, &pmc_kthread_mtx, PWAIT,
"pmcloop", 0);
continue;
}
TAILQ_REMOVE(&po->po_logbuffers, lb, plb_next);
+ if (po->po_flags & PMC_PO_SHUTDOWN)
+ last_buffer = TAILQ_EMPTY(&po->po_logbuffers);
mtx_unlock_spin(&po->po_mtx);
}
mtx_unlock(&pmc_kthread_mtx);
+sigpipe_retry:
/* process the request */
PMCDBG(LOG,WRI,2, "po=%p base=%p ptr=%p", po,
lb->plb_base, lb->plb_ptr);
@@ -328,7 +322,8 @@ pmclog_loop(void *arg)
if (error) {
/* XXX some errors are recoverable */
- /* XXX also check for SIGPIPE if a socket */
+ if (error == EPIPE)
+ goto sigpipe_retry;
/* send a SIGIO to the owner and exit */
PROC_LOCK(p);
@@ -344,6 +339,14 @@ pmclog_loop(void *arg)
break;
}
+ if (last_buffer) {
+ /*
+ * Close the file to get PMCLOG_EOF error
+ * in pmclog(3).
+ */
+ fo_close(po->po_file, curthread);
+ }
+
mtx_lock(&pmc_kthread_mtx);
/* put the used buffer back into the global pool */
@@ -425,6 +428,12 @@ pmclog_reserve(struct pmc_owner *po, int length)
mtx_lock_spin(&po->po_mtx);
+ /* No more data when shutdown in progress. */
+ if (po->po_flags & PMC_PO_SHUTDOWN) {
+ mtx_unlock_spin(&po->po_mtx);
+ return (NULL);
+ }
+
if (po->po_curbuf == NULL)
if (pmclog_get_buffer(po) != 0) {
mtx_unlock_spin(&po->po_mtx);
@@ -686,7 +695,7 @@ pmclog_deconfigure_log(struct pmc_owner *po)
int
pmclog_flush(struct pmc_owner *po)
{
- int error, has_pending_buffers;
+ int error;
PMCDBG(LOG,FLS,1, "po=%p", po);
@@ -714,16 +723,13 @@ pmclog_flush(struct pmc_owner *po)
mtx_lock_spin(&po->po_mtx);
if (po->po_curbuf)
pmclog_schedule_io(po);
- has_pending_buffers = !TAILQ_EMPTY(&po->po_logbuffers);
mtx_unlock_spin(&po->po_mtx);
- if (has_pending_buffers) {
- po->po_flags |= PMC_PO_IN_FLUSH; /* ask for a wakeup */
- error = msleep(po->po_kthread, &pmc_kthread_mtx, PWAIT,
- "pmcflush", 0);
- if (error == 0)
- error = po->po_error;
- }
+ /*
+ * Initiate shutdown: no new data queued,
+ * thread will close file on last block.
+ */
+ po->po_flags |= PMC_PO_SHUTDOWN;
error:
mtx_unlock(&pmc_kthread_mtx);
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index a689a9b..cfec777 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -759,7 +759,7 @@ struct pmc_owner {
};
#define PMC_PO_OWNS_LOGFILE 0x00000001 /* has a log file */
-#define PMC_PO_IN_FLUSH 0x00000010 /* in the middle of a flush */
+#define PMC_PO_SHUTDOWN 0x00000010 /* in the process of shutdown */
#define PMC_PO_INITIAL_MAPPINGS_DONE 0x00000020
/*
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index 5811af3..fc26001 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -1670,10 +1670,8 @@ pmcstat_print_log(void)
int
pmcstat_close_log(void)
{
- if (pmc_flush_logfile() < 0 ||
- pmc_configure_logfile(-1) < 0)
+ if (pmc_flush_logfile() < 0)
err(EX_OSERR, "ERROR: logging failed");
- args.pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
PMCSTAT_FINISHED);
}
OpenPOWER on IntegriCloud