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-head mailing list