svn commit: r334108 - in head: lib/libpmc lib/libpmcstat sys/sys usr.sbin/pmcstat
Matt Macy
mmacy at FreeBSD.org
Wed May 23 17:25:03 UTC 2018
Author: mmacy
Date: Wed May 23 17:25:00 2018
New Revision: 334108
URL: https://svnweb.freebsd.org/changeset/base/334108
Log:
hwpmc: add thread id field to callchain and context switch records to allow filtering
on thread in post-processing.
To generate stacks for just ${THREADID}:
pmcstat -R ${PREFIX}.pmcstat -L ${THREADID} -z100 -G ${PREFIX}.stacks
Sponsored by: Limelight Networks
Modified:
head/lib/libpmc/pmclog.c
head/lib/libpmc/pmclog.h
head/lib/libpmcstat/libpmcstat.h
head/lib/libpmcstat/libpmcstat_logging.c
head/sys/sys/pmc.h
head/sys/sys/pmclog.h
head/usr.sbin/pmcstat/pmcstat.c
Modified: head/lib/libpmc/pmclog.c
==============================================================================
--- head/lib/libpmc/pmclog.c Wed May 23 17:05:12 2018 (r334107)
+++ head/lib/libpmc/pmclog.c Wed May 23 17:25:00 2018 (r334108)
@@ -326,8 +326,10 @@ pmclog_get_event(void *cookie, char **data, ssize_t *l
switch (ev->pl_type = PMCLOG_HEADER_TO_TYPE(h)) {
case PMCLOG_TYPE_CALLCHAIN:
PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_pid);
+ PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_tid);
PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_pmcid);
PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_cpuflags);
+ PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_cpuflags2);
PMCLOG_GET_CALLCHAIN_SIZE(ev->pl_u.pl_cc.pl_npc,evlen);
for (npc = 0; npc < ev->pl_u.pl_cc.pl_npc; npc++)
PMCLOG_READADDR(le,ev->pl_u.pl_cc.pl_pc[npc]);
@@ -363,6 +365,7 @@ pmclog_get_event(void *cookie, char **data, ssize_t *l
PMCLOG_READADDR(le,ev->pl_u.pl_s.pl_pc);
PMCLOG_READ32(le,ev->pl_u.pl_s.pl_pmcid);
PMCLOG_READ32(le,ev->pl_u.pl_s.pl_usermode);
+ PMCLOG_READ32(le,ev->pl_u.pl_s.pl_tid);
break;
case PMCLOG_TYPE_PMCALLOCATE:
PMCLOG_READ32(le,ev->pl_u.pl_a.pl_pmcid);
@@ -393,6 +396,7 @@ pmclog_get_event(void *cookie, char **data, ssize_t *l
PMCLOG_READ32(le,ev->pl_u.pl_c.pl_pmcid);
PMCLOG_READ64(le,ev->pl_u.pl_c.pl_value);
PMCLOG_READ32(le,ev->pl_u.pl_c.pl_pid);
+ PMCLOG_READ32(le,ev->pl_u.pl_c.pl_tid);
break;
case PMCLOG_TYPE_PROCEXEC:
PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_procexec);
Modified: head/lib/libpmc/pmclog.h
==============================================================================
--- head/lib/libpmc/pmclog.h Wed May 23 17:05:12 2018 (r334107)
+++ head/lib/libpmc/pmclog.h Wed May 23 17:25:00 2018 (r334108)
@@ -47,8 +47,10 @@ enum pmclog_state {
struct pmclog_ev_callchain {
uint32_t pl_pid;
+ uint32_t pl_tid;
uint32_t pl_pmcid;
uint32_t pl_cpuflags;
+ uint32_t pl_cpuflags2;
uint32_t pl_npc;
uintfptr_t pl_pc[PMC_CALLCHAIN_DEPTH_MAX];
};
@@ -79,7 +81,9 @@ struct pmclog_ev_map_out {
struct pmclog_ev_pcsample {
uintfptr_t pl_pc;
pid_t pl_pid;
+ pid_t pl_tid;
pmc_id_t pl_pmcid;
+ uint32_t pl_flags;
uint32_t pl_usermode;
};
@@ -110,6 +114,7 @@ struct pmclog_ev_pmcdetach {
struct pmclog_ev_proccsw {
pid_t pl_pid;
+ pid_t pl_tid;
pmc_id_t pl_pmcid;
pmc_value_t pl_value;
};
Modified: head/lib/libpmcstat/libpmcstat.h
==============================================================================
--- head/lib/libpmcstat/libpmcstat.h Wed May 23 17:05:12 2018 (r334107)
+++ head/lib/libpmcstat/libpmcstat.h Wed May 23 17:25:00 2018 (r334108)
@@ -107,6 +107,7 @@ struct pmcstat_args {
#define FLAG_HAS_DURATION 0x00080000 /* -l secs */
#define FLAG_DO_WIDE_GPROF_HC 0x00100000 /* -e */
#define FLAG_SKIP_TOP_FN_RES 0x00200000 /* -I */
+#define FLAG_FILTER_THREAD_ID 0x00400000 /* -L */
int pa_required; /* required features */
int pa_pplugin; /* pre-processing plugin */
@@ -131,6 +132,7 @@ struct pmcstat_args {
int pa_topcolor; /* terminal support color */
int pa_mergepmc; /* merge PMC with same name */
double pa_duration; /* time duration */
+ uint32_t pa_tid;
int pa_argc;
char **pa_argv;
STAILQ_HEAD(, pmcstat_ev) pa_events;
Modified: head/lib/libpmcstat/libpmcstat_logging.c
==============================================================================
--- head/lib/libpmcstat/libpmcstat_logging.c Wed May 23 17:05:12 2018 (r334107)
+++ head/lib/libpmcstat/libpmcstat_logging.c Wed May 23 17:25:00 2018 (r334108)
@@ -313,6 +313,11 @@ pmcstat_analyze_log(struct pmcstat_args *args,
cpuflags = ev.pl_u.pl_cc.pl_cpuflags;
cpu = PMC_CALLCHAIN_CPUFLAGS_TO_CPU(cpuflags);
+ if ((args->pa_flags & FLAG_FILTER_THREAD_ID) &&
+ args->pa_tid != ev.pl_u.pl_cc.pl_tid) {
+ pmcstat_stats->ps_samples_skipped++;
+ break;
+ }
/* Filter on the CPU id. */
if (!CPU_ISSET(cpu, &(args->pa_cpumask))) {
pmcstat_stats->ps_samples_skipped++;
Modified: head/sys/sys/pmc.h
==============================================================================
--- head/sys/sys/pmc.h Wed May 23 17:05:12 2018 (r334107)
+++ head/sys/sys/pmc.h Wed May 23 17:25:00 2018 (r334108)
@@ -922,8 +922,10 @@ struct pmc_hw {
struct pmc_sample {
uint16_t ps_nsamples; /* callchain depth */
- uint8_t ps_cpu; /* cpu number */
- uint8_t ps_flags; /* other flags */
+ uint16_t ps_cpu; /* cpu number */
+ uint16_t ps_flags; /* other flags */
+ uint8_t ps_pad[2];
+ lwpid_t ps_tid; /* thread id */
pid_t ps_pid; /* process PID or -1 */
struct thread *ps_td; /* which thread */
struct pmc *ps_pmc; /* interrupting PMC */
Modified: head/sys/sys/pmclog.h
==============================================================================
--- head/sys/sys/pmclog.h Wed May 23 17:05:12 2018 (r334107)
+++ head/sys/sys/pmclog.h Wed May 23 17:25:00 2018 (r334108)
@@ -107,8 +107,10 @@ enum pmclog_type {
struct pmclog_callchain {
PMCLOG_ENTRY_HEADER
uint32_t pl_pid;
+ uint32_t pl_tid;
uint32_t pl_pmcid;
uint32_t pl_cpuflags;
+ uint32_t pl_cpuflags2;
/* 8 byte aligned */
uintptr_t pl_pc[PMC_CALLCHAIN_DEPTH_MAX];
} __packed;
@@ -152,6 +154,8 @@ struct pmclog_pcsample {
uintfptr_t pl_pc; /* 8 byte aligned */
uint32_t pl_pmcid;
uint32_t pl_usermode;
+ uint32_t pl_tid;
+ uint32_t pl_pad;
} __packed;
struct pmclog_pmcallocate {
@@ -179,6 +183,7 @@ struct pmclog_proccsw {
uint32_t pl_pmcid;
uint64_t pl_value; /* keep 8 byte aligned */
uint32_t pl_pid;
+ uint32_t pl_tid;
} __packed;
struct pmclog_procexec {
@@ -275,7 +280,7 @@ void pmclog_process_pmcallocate(struct pmc *_pm);
void pmclog_process_pmcattach(struct pmc *_pm, pid_t _pid, char *_path);
void pmclog_process_pmcdetach(struct pmc *_pm, pid_t _pid);
void pmclog_process_proccsw(struct pmc *_pm, struct pmc_process *_pp,
- pmc_value_t _v);
+ pmc_value_t _v, struct thread *);
void pmclog_process_procexec(struct pmc_owner *_po, pmc_id_t _pmid, pid_t _pid,
uintfptr_t _startaddr, char *_path);
void pmclog_process_procexit(struct pmc *_pm, struct pmc_process *_pp);
Modified: head/usr.sbin/pmcstat/pmcstat.c
==============================================================================
--- head/usr.sbin/pmcstat/pmcstat.c Wed May 23 17:05:12 2018 (r334107)
+++ head/usr.sbin/pmcstat/pmcstat.c Wed May 23 17:25:00 2018 (r334108)
@@ -500,7 +500,7 @@ main(int argc, char **argv)
CPU_COPY(&rootmask, &cpumask);
while ((option = getopt(argc, argv,
- "CD:EF:G:IM:NO:P:R:S:TWa:c:def:gk:l:m:n:o:p:qr:s:t:vw:z:")) != -1)
+ "CD:EF:G:IL:M:NO:P:R:S:TWa:c:def:gk:l:m:n:o:p:qr:s:t:vw:z:")) != -1)
switch (option) {
case 'a': /* Annotate + callgraph */
args.pa_flags |= FLAG_DO_ANNOTATE;
@@ -581,6 +581,10 @@ main(int argc, char **argv)
args.pa_flags |= FLAG_HAS_KERNELPATH;
break;
+ case 'L':
+ args.pa_flags |= FLAG_FILTER_THREAD_ID;
+ args.pa_tid = strtol(optarg, &end, 0);
+ break;
case 'l': /* time duration in seconds */
duration = strtod(optarg, &end);
if (*end != '\0' || duration <= 0)
More information about the svn-src-all
mailing list