summaryrefslogtreecommitdiffstats
path: root/lib/libpmc
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2012-03-28 20:58:30 +0000
committerfabient <fabient@FreeBSD.org>2012-03-28 20:58:30 +0000
commit5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15 (patch)
treefadff08d26576c3d5c1cef9d47abd784602b237a /lib/libpmc
parent9a7982e5a0267c0421856f3a43a1ae75880058f3 (diff)
downloadFreeBSD-src-5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15.zip
FreeBSD-src-5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15.tar.gz
Add software PMC support.
New kernel events can be added at various location for sampling or counting. This will for example allow easy system profiling whatever the processor is with known tools like pmcstat(8). Simultaneous usage of software PMC and hardware PMC is possible, for example looking at the lock acquire failure, page fault while sampling on instructions. Sponsored by: NETASQ MFC after: 1 month
Diffstat (limited to 'lib/libpmc')
-rw-r--r--lib/libpmc/Makefile1
-rw-r--r--lib/libpmc/libpmc.c118
-rw-r--r--lib/libpmc/pmc.33
-rw-r--r--lib/libpmc/pmc.atom.31
-rw-r--r--lib/libpmc/pmc.core.31
-rw-r--r--lib/libpmc/pmc.core2.31
-rw-r--r--lib/libpmc/pmc.corei7.31
-rw-r--r--lib/libpmc/pmc.corei7uc.31
-rw-r--r--lib/libpmc/pmc.iaf.31
-rw-r--r--lib/libpmc/pmc.k7.31
-rw-r--r--lib/libpmc/pmc.k8.31
-rw-r--r--lib/libpmc/pmc.mips24k.31
-rw-r--r--lib/libpmc/pmc.octeon.31
-rw-r--r--lib/libpmc/pmc.p4.31
-rw-r--r--lib/libpmc/pmc.p5.31
-rw-r--r--lib/libpmc/pmc.p6.31
-rw-r--r--lib/libpmc/pmc.sandybridge.31
-rw-r--r--lib/libpmc/pmc.sandybridgeuc.31
-rw-r--r--lib/libpmc/pmc.soft.3104
-rw-r--r--lib/libpmc/pmc.tsc.31
-rw-r--r--lib/libpmc/pmc.ucf.31
-rw-r--r--lib/libpmc/pmc.westmere.31
-rw-r--r--lib/libpmc/pmc.westmereuc.31
-rw-r--r--lib/libpmc/pmc.xscale.31
-rw-r--r--lib/libpmc/pmclog.c6
-rw-r--r--lib/libpmc/pmclog.h8
26 files changed, 234 insertions, 26 deletions
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
index 95da88e..5edbfe6 100644
--- a/lib/libpmc/Makefile
+++ b/lib/libpmc/Makefile
@@ -20,6 +20,7 @@ MAN+= pmc_read.3
MAN+= pmc_set.3
MAN+= pmc_start.3
MAN+= pmclog.3
+MAN+= pmc.soft.3
# PMC-dependent manual pages
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 4323171..3b7dc37 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
-
#if defined(__mips__)
static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif /* __mips__ */
+static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
#if defined(__powerpc__)
static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec,
@@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON);
PMC_CLASSDEP_TABLE(ucf, UCF);
PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
+static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
+
#undef __PMC_EV_ALIAS
#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },
@@ -215,21 +218,22 @@ static const struct pmc_event_descr westmereuc_event_table[] =
PMC_CLASS_##C, __VA_ARGS__ \
}
-PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE);
-PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K);
-PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON);
-PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
+PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
+PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
+PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
#if defined(__XSCALE__)
PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
#endif
-
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
#endif /* __mips__ */
-
#if defined(__powerpc__)
PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450);
#endif
+static struct pmc_class_descr soft_class_table_descr =
+{
+ .pm_evc_name = "SOFT-",
+ .pm_evc_name_size = sizeof("SOFT-") - 1,
+ .pm_evc_class = PMC_CLASS_SOFT,
+ .pm_evc_event_table = NULL,
+ .pm_evc_event_table_size = 0,
+ .pm_evc_allocate_pmc = soft_allocate_pmc
+};
+
#undef PMC_CLASS_TABLE_DESC
static const struct pmc_class_descr **pmc_class_table;
@@ -343,9 +355,12 @@ static const char * pmc_state_names[] = {
__PMC_STATES()
};
-static int pmc_syscall = -1; /* filled in by pmc_init() */
-
-static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */
+/*
+ * Filled in by pmc_init().
+ */
+static int pmc_syscall = -1;
+static struct pmc_cpuinfo cpu_info;
+static struct pmc_op_getdyneventinfo soft_event_info;
/* Event masks for events */
struct pmc_masks {
@@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
}
#endif
+static struct pmc_event_alias generic_aliases[] = {
+ EV_ALIAS("instructions", "SOFT-CLOCK.HARD"),
+ EV_ALIAS(NULL, NULL)
+};
+
+static int
+soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ (void)ctrspec;
+ (void)pmc_config;
+
+ if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST)
+ return (-1);
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+ return (0);
+}
+
#if defined(__XSCALE__)
static struct pmc_event_alias xscale_aliases[] = {
@@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = ppc7450_event_table;
count = PMC_EVENT_TABLE_SIZE(ppc7450);
break;
+ case PMC_CLASS_SOFT:
+ ev = soft_event_table;
+ count = soft_event_info.pm_nevent;
+ break;
default:
errno = EINVAL;
return (-1);
@@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
for (;count--; ev++, names++)
*names = ev->pm_ev_name;
+
return (0);
}
@@ -2780,11 +2819,34 @@ pmc_init(void)
pmc_class_table[n] = NULL;
/*
+ * Get soft events list.
+ */
+ soft_event_info.pm_class = PMC_CLASS_SOFT;
+ if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
+ return (pmc_syscall = -1);
+
+ /* Map soft events to static list. */
+ for (n = 0; n < soft_event_info.pm_nevent; n++) {
+ soft_event_table[n].pm_ev_name =
+ soft_event_info.pm_events[n].pm_ev_name;
+ soft_event_table[n].pm_ev_code =
+ soft_event_info.pm_events[n].pm_ev_code;
+ }
+ soft_class_table_descr.pm_evc_event_table_size = \
+ soft_event_info.pm_nevent;
+ soft_class_table_descr.pm_evc_event_table = \
+ soft_event_table;
+
+ /*
* Fill in the class table.
*/
n = 0;
+
+ /* Fill soft events information. */
+ pmc_class_table[n++] = &soft_class_table_descr;
#if defined(__amd64__) || defined(__i386__)
- pmc_class_table[n++] = &tsc_class_table_descr;
+ if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
+ pmc_class_table[n++] = &tsc_class_table_descr;
/*
* Check if this CPU has fixed function counters.
@@ -2867,6 +2929,9 @@ pmc_init(void)
pmc_class_table[n] = &p4_class_table_descr;
break;
#endif
+ case PMC_CPU_GENERIC:
+ PMC_MDEP_INIT(generic);
+ break;
#if defined(__XSCALE__)
case PMC_CPU_INTEL_XSCALE:
PMC_MDEP_INIT(xscale);
@@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale);
} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
ev = mips24k_event_table;
- evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k
-);
+ evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
} else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) {
ev = octeon_event_table;
evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon);
} else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
ev = ppc7450_event_table;
- evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450
-);
+ evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
+ } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) {
+ ev = soft_event_table;
+ evfence = soft_event_table + soft_event_info.pm_nevent;
}
for (; ev != evfence; ev++)
diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3
index 0a537a5..cf74f32 100644
--- a/lib/libpmc/pmc.3
+++ b/lib/libpmc/pmc.3
@@ -223,6 +223,8 @@ and
CPUs.
.It Li PMC_CLASS_TSC
The timestamp counter on i386 and amd64 architecture CPUs.
+.It Li PMC_CLASS_SOFT
+Software events.
.El
.Ss PMC Capabilities
Capabilities of performance monitoring hardware are denoted using
@@ -525,6 +527,7 @@ API is
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4 ,
diff --git a/lib/libpmc/pmc.atom.3 b/lib/libpmc/pmc.atom.3
index 2ebb804..f61a141 100644
--- a/lib/libpmc/pmc.atom.3
+++ b/lib/libpmc/pmc.atom.3
@@ -1176,6 +1176,7 @@ and the underlying hardware events used on these CPUs.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.core.3 b/lib/libpmc/pmc.core.3
index 512e492..73b2cea 100644
--- a/lib/libpmc/pmc.core.3
+++ b/lib/libpmc/pmc.core.3
@@ -792,6 +792,7 @@ may not count some transitions.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.core2.3 b/lib/libpmc/pmc.core2.3
index 56c015b..5c6b533 100644
--- a/lib/libpmc/pmc.core2.3
+++ b/lib/libpmc/pmc.core2.3
@@ -1107,6 +1107,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.corei7.3 b/lib/libpmc/pmc.corei7.3
index 8e09250..aaf1f02 100644
--- a/lib/libpmc/pmc.corei7.3
+++ b/lib/libpmc/pmc.corei7.3
@@ -1559,6 +1559,7 @@ Counts number of segment register loads.
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.corei7uc.3 b/lib/libpmc/pmc.corei7uc.3
index c926980..3114c8e 100644
--- a/lib/libpmc/pmc.corei7uc.3
+++ b/lib/libpmc/pmc.corei7uc.3
@@ -863,6 +863,7 @@ refreshed or needs to go into a power down mode.
.Xr pmc.corei7 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.iaf.3 b/lib/libpmc/pmc.iaf.3
index aa39a7c..7e623d6 100644
--- a/lib/libpmc/pmc.iaf.3
+++ b/lib/libpmc/pmc.iaf.3
@@ -132,6 +132,7 @@ CPU, use the event specifier
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.k7.3 b/lib/libpmc/pmc.k7.3
index 59e6489..646f352 100644
--- a/lib/libpmc/pmc.k7.3
+++ b/lib/libpmc/pmc.k7.3
@@ -249,6 +249,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.k8.3 b/lib/libpmc/pmc.k8.3
index e4eb081..628137d 100644
--- a/lib/libpmc/pmc.k8.3
+++ b/lib/libpmc/pmc.k8.3
@@ -783,6 +783,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.mips24k.3 b/lib/libpmc/pmc.mips24k.3
index dc49f09..4acb0a7 100644
--- a/lib/libpmc/pmc.mips24k.3
+++ b/lib/libpmc/pmc.mips24k.3
@@ -392,6 +392,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.octeon.3 b/lib/libpmc/pmc.octeon.3
index d0ef3de..be38dd8 100644
--- a/lib/libpmc/pmc.octeon.3
+++ b/lib/libpmc/pmc.octeon.3
@@ -232,6 +232,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.p4.3 b/lib/libpmc/pmc.p4.3
index 3d89fc1..b273edd 100644
--- a/lib/libpmc/pmc.p4.3
+++ b/lib/libpmc/pmc.p4.3
@@ -1208,6 +1208,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.p5.3 b/lib/libpmc/pmc.p5.3
index dae43e3..ebdd505 100644
--- a/lib/libpmc/pmc.p5.3
+++ b/lib/libpmc/pmc.p5.3
@@ -444,6 +444,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p4 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.p6.3 b/lib/libpmc/pmc.p6.3
index 2033cce..3fa98a7 100644
--- a/lib/libpmc/pmc.p6.3
+++ b/lib/libpmc/pmc.p6.3
@@ -1010,6 +1010,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.sandybridge.3 b/lib/libpmc/pmc.sandybridge.3
index d530d15..e0c7eb9 100644
--- a/lib/libpmc/pmc.sandybridge.3
+++ b/lib/libpmc/pmc.sandybridge.3
@@ -907,6 +907,7 @@ Split locks in SQ.
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
.Xr pmc.sandybridgeuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc.ucf 3 ,
.Xr pmc.westmere 3 ,
diff --git a/lib/libpmc/pmc.sandybridgeuc.3 b/lib/libpmc/pmc.sandybridgeuc.3
index 19904b3..2078482 100644
--- a/lib/libpmc/pmc.sandybridgeuc.3
+++ b/lib/libpmc/pmc.sandybridgeuc.3
@@ -208,6 +208,7 @@ Counts the number of core-outgoing entries in the coherent tracker queue.
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
.Xr pmc.sandybridge 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc.ucf 3 ,
.Xr pmc.westmere 3 ,
diff --git a/lib/libpmc/pmc.soft.3 b/lib/libpmc/pmc.soft.3
new file mode 100644
index 0000000..f7d0cb0
--- /dev/null
+++ b/lib/libpmc/pmc.soft.3
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2012 Fabien Thomas. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 28, 2012
+.Os
+.Dt PMC.SOFT 3
+.Sh NAME
+.Nm pmc.soft
+.Nd measurements using software based events
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+Software events are used to collect various source of software events.
+.Ss PMC Features
+16 sampling counters using software events based on various sources.
+These PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta \&No
+.It PMC_CAP_INTERRUPT Ta Yes
+.It PMC_CAP_INVERT Ta \&No
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta Yes
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta \&No
+.It PMC_CAP_USER Ta Yes
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+There is no supported event qualifier.
+.Pp
+The event specifiers supported by software are:
+.Bl -tag -width indent
+.It Li CLOCK.HARD
+Hard clock ticks.
+.It Li CLOCK.STAT
+Stat clock ticks.
+.It Li LOCK.FAILED
+Lock acquisition failed.
+.It Li PAGE_FAULT.ALL
+All page fault type.
+.It Li PAGE_FAULT.READ
+Read page fault.
+.It Li PAGE_FAULT.WRITE
+Write page fault.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
+Software PMC was written by
+.An "Fabien Thomas"
+.Aq fabient@FreeBSD.org .
diff --git a/lib/libpmc/pmc.tsc.3 b/lib/libpmc/pmc.tsc.3
index 1abda30..2692005 100644
--- a/lib/libpmc/pmc.tsc.3
+++ b/lib/libpmc/pmc.tsc.3
@@ -68,6 +68,7 @@ maps to the TSC.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
.Sh HISTORY
diff --git a/lib/libpmc/pmc.ucf.3 b/lib/libpmc/pmc.ucf.3
index 5a908f5..15399e4 100644
--- a/lib/libpmc/pmc.ucf.3
+++ b/lib/libpmc/pmc.ucf.3
@@ -96,6 +96,7 @@ offset C0H under device number 0 and Function 0.
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.westmere.3 b/lib/libpmc/pmc.westmere.3
index b80aefa..547ee71 100644
--- a/lib/libpmc/pmc.westmere.3
+++ b/lib/libpmc/pmc.westmere.3
@@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shift or move operations.
.Xr pmc.corei7 3 ,
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.westmereuc.3 b/lib/libpmc/pmc.westmereuc.3
index c322778..517c470 100644
--- a/lib/libpmc/pmc.westmereuc.3
+++ b/lib/libpmc/pmc.westmereuc.3
@@ -1066,6 +1066,7 @@ disabled.
.Xr pmc.corei7 3 ,
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.xscale.3 b/lib/libpmc/pmc.xscale.3
index 25e78e2..521cc9c 100644
--- a/lib/libpmc/pmc.xscale.3
+++ b/lib/libpmc/pmc.xscale.3
@@ -134,6 +134,7 @@ and the underlying hardware events used.
.Xr pmc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
+.Xr pmc.soft 3 ,
.Xr hwpmc 4
.Sh HISTORY
The
diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c
index d9ebc67..26ec9dd 100644
--- a/lib/libpmc/pmclog.c
+++ b/lib/libpmc/pmclog.c
@@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len,
== NULL)
goto error;
break;
+ case PMCLOG_TYPE_PMCALLOCATEDYN:
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid);
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event);
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags);
+ PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX);
+ break;
case PMCLOG_TYPE_PMCATTACH:
PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach);
PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid);
diff --git a/lib/libpmc/pmclog.h b/lib/libpmc/pmclog.h
index b7c9c84..2a50945 100644
--- a/lib/libpmc/pmclog.h
+++ b/lib/libpmc/pmclog.h
@@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate {
pmc_id_t pl_pmcid;
};
+struct pmclog_ev_pmcallocatedyn {
+ uint32_t pl_event;
+ char pl_evname[PMC_NAME_MAX];
+ uint32_t pl_flags;
+ pmc_id_t pl_pmcid;
+};
+
struct pmclog_ev_pmcattach {
pmc_id_t pl_pmcid;
pid_t pl_pid;
@@ -146,6 +153,7 @@ struct pmclog_ev {
struct pmclog_ev_map_out pl_mo;
struct pmclog_ev_pcsample pl_s;
struct pmclog_ev_pmcallocate pl_a;
+ struct pmclog_ev_pmcallocatedyn pl_ad;
struct pmclog_ev_pmcattach pl_t;
struct pmclog_ev_pmcdetach pl_d;
struct pmclog_ev_proccsw pl_c;
OpenPOWER on IntegriCloud