diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/hwpmc/hwpmc_logging.c | 57 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_mod.c | 22 | ||||
-rw-r--r-- | sys/sys/pmc.h | 3 | ||||
-rw-r--r-- | sys/sys/pmclog.h | 1 |
4 files changed, 64 insertions, 19 deletions
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index c0f8b0d..5f5cd90 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -238,7 +238,7 @@ pmclog_get_buffer(struct pmc_owner *po) static void pmclog_loop(void *arg) { - int error, last_buffer; + int error; struct pmc_owner *po; struct pmclog_buffer *lb; struct proc *p; @@ -253,7 +253,6 @@ 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); @@ -286,14 +285,22 @@ pmclog_loop(void *arg) if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) { mtx_unlock_spin(&po->po_mtx); + if (po->po_flags & PMC_PO_SHUTDOWN) { + mtx_unlock(&pmc_kthread_mtx); + /* + * Close the file to get PMCLOG_EOF + * error in pmclog(3). + */ + fo_close(po->po_file, curthread); + mtx_lock(&pmc_kthread_mtx); + } + (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); } @@ -336,14 +343,6 @@ 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 */ @@ -693,6 +692,7 @@ int pmclog_flush(struct pmc_owner *po) { int error; + struct pmclog_buffer *lb; PMCDBG(LOG,FLS,1, "po=%p", po); @@ -715,11 +715,38 @@ pmclog_flush(struct pmc_owner *po) } /* - * Schedule the current buffer if any. + * Schedule the current buffer if any and not empty. + */ + mtx_lock_spin(&po->po_mtx); + lb = po->po_curbuf; + if (lb && lb->plb_ptr != lb->plb_base) { + pmclog_schedule_io(po); + } else + error = ENOBUFS; + mtx_unlock_spin(&po->po_mtx); + + error: + mtx_unlock(&pmc_kthread_mtx); + + return (error); +} + +int +pmclog_close(struct pmc_owner *po) +{ + + PMCDBG(LOG,CLO,1, "po=%p", po); + + mtx_lock(&pmc_kthread_mtx); + + /* + * Schedule the current buffer. */ mtx_lock_spin(&po->po_mtx); if (po->po_curbuf) pmclog_schedule_io(po); + else + wakeup_one(po); mtx_unlock_spin(&po->po_mtx); /* @@ -728,13 +755,11 @@ pmclog_flush(struct pmc_owner *po) */ po->po_flags |= PMC_PO_SHUTDOWN; - error: mtx_unlock(&pmc_kthread_mtx); - return (error); + return (0); } - void pmclog_process_callchain(struct pmc *pm, struct pmc_sample *ps) { diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index fc82908..7ca7a47 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -2891,7 +2891,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) error = pmclog_configure_log(md, po, cl.pm_logfd); } else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { pmclog_process_closelog(po); - error = pmclog_flush(po); + error = pmclog_close(po); if (error == 0) { LIST_FOREACH(pm, &po->po_pmcs, pm_next) if (pm->pm_flags & PMC_F_NEEDS_LOGFILE && @@ -2907,7 +2907,6 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) } break; - /* * Flush a log file. */ @@ -2928,6 +2927,25 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) break; /* + * Close a log file. + */ + + case PMC_OP_CLOSELOG: + { + struct pmc_owner *po; + + sx_assert(&pmc_sx, SX_XLOCKED); + + if ((po = pmc_find_owner_descriptor(td->td_proc)) == NULL) { + error = EINVAL; + break; + } + + error = pmclog_close(po); + } + break; + + /* * Retrieve hardware configuration. */ diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index bcc2898..6819ece 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -302,7 +302,8 @@ enum pmc_event { __PMC_OP(PMCSETCOUNT, "Set initial count/sampling rate") \ __PMC_OP(PMCSTART, "Start a PMC") \ __PMC_OP(PMCSTOP, "Stop a PMC") \ - __PMC_OP(WRITELOG, "Write a cookie to the log file") + __PMC_OP(WRITELOG, "Write a cookie to the log file") \ + __PMC_OP(CLOSELOG, "Close log file") enum pmc_ops { diff --git a/sys/sys/pmclog.h b/sys/sys/pmclog.h index 44c5c6c..f2b6480 100644 --- a/sys/sys/pmclog.h +++ b/sys/sys/pmclog.h @@ -243,6 +243,7 @@ int pmclog_configure_log(struct pmc_mdep *_md, struct pmc_owner *_po, int _logfd); int pmclog_deconfigure_log(struct pmc_owner *_po); int pmclog_flush(struct pmc_owner *_po); +int pmclog_close(struct pmc_owner *_po); void pmclog_initialize(void); void pmclog_process_callchain(struct pmc *_pm, struct pmc_sample *_ps); void pmclog_process_closelog(struct pmc_owner *po); |