aboutsummaryrefslogtreecommitdiff
path: root/lib/libpmc
diff options
context:
space:
mode:
authorAli Mashtizadeh <ali@mashtizadeh.com>2026-04-08 05:36:53 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2026-04-24 15:33:42 +0000
commit576c6e9620dff3e92f3c5d1e5be4d92c9eb29828 (patch)
tree274524de9006e6e9441d730963be5b6da8fac4c8 /lib/libpmc
parent87ed6840a0a6320295f6abb43a987d20ae126cf7 (diff)
Diffstat (limited to 'lib/libpmc')
-rw-r--r--lib/libpmc/libpmc.c29
-rw-r--r--lib/libpmc/pmc.ibs.310
2 files changed, 34 insertions, 5 deletions
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index ebb642e8d16b..562000aef4e4 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -32,6 +32,10 @@
#include <sys/pmc.h>
#include <sys/syscall.h>
+#if defined(__amd64__) || defined(__i386__)
+#include <machine/cpufunc.h>
+#endif
+
#include <ctype.h>
#include <errno.h>
#include <err.h>
@@ -697,6 +701,8 @@ ibs_allocate_pmc(enum pmc_event pe, char *ctrspec,
{
char *e, *p, *q;
uint64_t ctl, ldlat;
+ u_int ibs_features;
+ u_int regs[4];
pmc_config->pm_caps |=
(PMC_CAP_SYSTEM | PMC_CAP_EDGE | PMC_CAP_PRECISE);
@@ -719,11 +725,22 @@ ibs_allocate_pmc(enum pmc_event pe, char *ctrspec,
return (-1);
}
+ /* Read the ibs feature flags */
+ ibs_features = 0;
+ do_cpuid(0x80000000, regs);
+ if (regs[0] >= CPUID_IBSID) {
+ do_cpuid(CPUID_IBSID, regs);
+ ibs_features = regs[0];
+ }
+
/* parse parameters */
ctl = 0;
if (pe == PMC_EV_IBS_FETCH) {
while ((p = strsep(&ctrspec, ",")) != NULL) {
if (KWMATCH(p, "l3miss")) {
+ if ((ibs_features & CPUID_IBSID_ZEN4IBSEXTENSIONS) == 0)
+ return (-1);
+
ctl |= IBS_FETCH_CTL_L3MISSONLY;
} else if (KWMATCH(p, "randomize")) {
ctl |= IBS_FETCH_CTL_RANDOMIZE;
@@ -742,6 +759,9 @@ ibs_allocate_pmc(enum pmc_event pe, char *ctrspec,
if (KWMATCH(p, "l3miss")) {
ctl |= IBS_OP_CTL_L3MISSONLY;
} else if (KWPREFIXMATCH(p, "ldlat=")) {
+ if ((ibs_features & CPUID_IBSID_IBSLOADLATENCYFILT) == 0)
+ return (-1);
+
q = strchr(p, '=');
if (*++q == '\0') /* skip '=' */
return (-1);
@@ -765,7 +785,10 @@ ibs_allocate_pmc(enum pmc_event pe, char *ctrspec,
return (-1);
ctl |= IBS_OP_CTL_LDLAT_TO_CTL(ldlat);
ctl |= IBS_OP_CTL_L3MISSONLY | IBS_OP_CTL_LATFLTEN;
- } else if (KWMATCH(p, "randomize")) {
+ } else if (KWMATCH(p, "opcount")) {
+ if ((ibs_features & CPUID_IBSID_OPCNT) == 0)
+ return (-1);
+
ctl |= IBS_OP_CTL_COUNTERCONTROL;
} else {
return (-1);
@@ -776,6 +799,10 @@ ibs_allocate_pmc(enum pmc_event pe, char *ctrspec,
pmc_config->pm_count > IBS_OP_MAX_RATE)
return (-1);
+ if (((ibs_features & CPUID_IBSID_OPCNTEXT) == 0) &&
+ (pmc_config->pm_count > IBS_OP_MAX_RATE_PREEXT))
+ return (-1);
+
ctl |= IBS_OP_INTERVAL_TO_CTL(pmc_config->pm_count);
}
diff --git a/lib/libpmc/pmc.ibs.3 b/lib/libpmc/pmc.ibs.3
index f0534a0955d2..574db4df6fa1 100644
--- a/lib/libpmc/pmc.ibs.3
+++ b/lib/libpmc/pmc.ibs.3
@@ -107,6 +107,8 @@ IBS only supports filtering latencies that are a multiple of 128 and between
128 and 2048.
Load latency filtering can only be used with ibs-op events and imply the
l3miss qualifier.
+.It Li opcount
+Count ops rather than cycles.
.It Li randomize
Randomize the sampling rate.
.El
@@ -124,13 +126,13 @@ qualifier randomly sets the bottom four bits of the sample rate.
.It Li ibs-op Xo
.Op ,l3miss
.Op ,ldlat= Ns Ar ldlat
-.Op ,randomize
+.Op ,opcount
.Xc
Collect performance samples during instruction execution.
The
-.Ar randomize
-qualifier, upon reaching the maximum count, restarts the count with a value
-between 1 and 127.
+.Ar opcount
+qualifier, upon reaching the maximum count, restarts the count with a random
+value between 1 and 127.
.El
.Pp
You may collect both events at the same time.