Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103905942
D35342.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D35342.diff
View Options
diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3
--- a/lib/libpmc/pmc.3
+++ b/lib/libpmc/pmc.3
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 10, 2021
+.Dd May 28, 2022
.Dt PMC 3
.Os
.Sh NAME
@@ -200,6 +200,8 @@
.Bl -tag -width "Li PMC_CAP_INTERRUPT" -compact
.It Li PMC_CAP_CASCADE
The ability to cascade counters.
+.It Li PMC_CAP_DOMWIDE
+Separate counters tied to each NUMA domain.
.It Li PMC_CAP_EDGE
The ability to count negated to asserted transitions of the hardware
conditions being probed for.
@@ -218,6 +220,8 @@
.It Li PMC_CAP_SYSTEM
The ability to restrict counting of hardware events to when the CPU is
running privileged code.
+.It Li PMC_CAP_SYSWIDE
+A single counter aggregating events for the whole system.
.It Li PMC_CAP_THRESHOLD
The ability to ignore simultaneous hardware events below a
programmable threshold.
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -171,7 +171,10 @@
__PMC_CLASS(MIPS74K, 0x12, "MIPS 74K") \
__PMC_CLASS(E500, 0x13, "Freescale e500 class") \
__PMC_CLASS(BERI, 0x14, "MIPS BERI") \
- __PMC_CLASS(POWER8, 0x15, "IBM POWER8 class")
+ __PMC_CLASS(POWER8, 0x15, "IBM POWER8 class") \
+ __PMC_CLASS(DMC620_PMU_CD2, 0x16, "ARM DMC620 Memory Controller PMU CLKDIV2") \
+ __PMC_CLASS(DMC620_PMU_C, 0x17, "ARM DMC620 Memory Controller PMU CLK") \
+ __PMC_CLASS(CMN600_PMU, 0x18, "Arm CoreLink CMN600 Coherent Mesh Network PMU")
enum pmc_class {
#undef __PMC_CLASS
@@ -180,7 +183,7 @@
};
#define PMC_CLASS_FIRST PMC_CLASS_TSC
-#define PMC_CLASS_LAST PMC_CLASS_POWER8
+#define PMC_CLASS_LAST PMC_CLASS_CMN600_PMU
/*
* A PMC can be in the following states:
@@ -308,7 +311,9 @@
__PMC_CAP(QUALIFIER, 8, "further qualify monitored events") \
__PMC_CAP(PRECISE, 9, "perform precise sampling") \
__PMC_CAP(TAGGING, 10, "tag upstream events") \
- __PMC_CAP(CASCADE, 11, "cascade counters")
+ __PMC_CAP(CASCADE, 11, "cascade counters") \
+ __PMC_CAP(SYSWIDE, 12, "system wide counter") \
+ __PMC_CAP(DOMWIDE, 13, "NUMA domain wide counter")
enum pmc_caps
{
@@ -318,7 +323,7 @@
};
#define PMC_CAP_FIRST PMC_CAP_INTERRUPT
-#define PMC_CAP_LAST PMC_CAP_CASCADE
+#define PMC_CAP_LAST PMC_CAP_DOMWIDE
/*
* PMC Event Numbers
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -59,6 +59,7 @@
#include <regex.h>
#include <signal.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -116,6 +117,7 @@
static kvm_t *pmcstat_kvm;
static struct kinfo_proc *pmcstat_plist;
struct pmcstat_args args;
+static bool libpmc_initialized = false;
static void
pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask)
@@ -419,6 +421,22 @@
endwin();
}
+static inline void
+libpmc_initialize(int *npmc)
+{
+
+ if (libpmc_initialized)
+ return;
+ if (pmc_init() < 0)
+ err(EX_UNAVAILABLE, "ERROR: Initialization of the pmc(3)"
+ " library failed");
+
+ /* assume all CPUs are identical */
+ if ((*npmc = pmc_npmc(0)) < 0)
+ err(EX_OSERR, "ERROR: Cannot determine the number of PMCs on "
+ "CPU %d", 0);
+ libpmc_initialized = true;
+}
/*
* Main
*/
@@ -426,14 +444,14 @@
int
main(int argc, char **argv)
{
- cpuset_t cpumask, rootmask;
+ cpuset_t cpumask, dommask, rootmask;
double interval;
double duration;
int option, npmc;
int c, check_driver_stats;
int do_callchain, do_descendants, do_logproccsw, do_logprocexit;
- int do_print, do_read, do_listcounters, do_descr;
- int do_userspace;
+ int do_print, do_read, do_listcounters, do_descr, domains;
+ int do_userspace, i;
size_t len;
int graphdepth;
int pipefd[2], rfd;
@@ -450,6 +468,7 @@
struct winsize ws;
struct stat sb;
char buffer[PATH_MAX];
+ uint32_t caps;
check_driver_stats = 0;
current_sampling_count = 0;
@@ -460,6 +479,7 @@
do_logproccsw = 0;
do_logprocexit = 0;
do_listcounters = 0;
+ domains = 0;
use_cumulative_counts = 0;
graphfilename = "-";
args.pa_required = 0;
@@ -489,8 +509,10 @@
bzero(&ds_end, sizeof(ds_end));
ev = NULL;
event = NULL;
+ caps = 0;
CPU_ZERO(&cpumask);
+
/* Default to using the running system kernel. */
len = 0;
if (sysctlbyname("kern.bootfile", NULL, &len, NULL, 0) == -1)
@@ -500,6 +522,9 @@
errx(EX_SOFTWARE, "ERROR: Out of memory.");
if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1)
err(EX_OSERR, "ERROR: Cannot determine path of running kernel");
+ len = sizeof(domains);
+ if (sysctlbyname("vm.ndomains", &domains, &len, NULL, 0) == -1)
+ err(EX_OSERR, "ERROR: Cannot get number of domains");
/*
* The initial CPU mask specifies the root mask of this process
@@ -640,6 +665,7 @@
case 's': /* system-wide counting PMC */
case 'P': /* process virtual sampling PMC */
case 'S': /* system-wide sampling PMC */
+ caps = 0;
if ((ev = malloc(sizeof(*ev))) == NULL)
errx(EX_SOFTWARE, "ERROR: Out of memory.");
@@ -707,12 +733,48 @@
errx(EX_SOFTWARE, "ERROR: Out of memory.");
(void) strncpy(ev->ev_name, optarg, c);
*(ev->ev_name + c) = '\0';
+ libpmc_initialize(&npmc);
+ if (args.pa_flags & FLAG_HAS_SYSTEM_PMCS) {
+ if (pmc_allocate(ev->ev_spec, ev->ev_mode,
+ ev->ev_flags, ev->ev_cpu, &ev->ev_pmcid,
+ ev->ev_count) < 0)
+ err(EX_OSERR, "ERROR: Cannot allocate "
+ "system-mode pmc with specification"
+ " \"%s\"", ev->ev_spec);
+ if (pmc_capabilities(ev->ev_pmcid, &caps)) {
+ pmc_release(ev->ev_pmcid);
+ err(EX_OSERR, "ERROR: Cannot get pmc "
+ "capabilities");
+ }
+ }
+
STAILQ_INSERT_TAIL(&args.pa_events, ev, ev_next);
+ if ((caps & PMC_CAP_SYSWIDE) == PMC_CAP_SYSWIDE)
+ break;
+ if ((caps & PMC_CAP_DOMWIDE) == PMC_CAP_DOMWIDE) {
+ CPU_ZERO(&cpumask);
+ /*
+ * Get number of domains and allocate one
+ * counter in each.
+ * First already allocated.
+ */
+ for (i = 1; i < domains; i++) {
+ CPU_ZERO(&dommask);
+ cpuset_getaffinity(CPU_LEVEL_WHICH,
+ CPU_WHICH_DOMAIN, i, sizeof(dommask),
+ &dommask);
+ CPU_SET(CPU_FFS(&dommask) - 1, &cpumask);
+ }
+ args.pa_flags |= FLAGS_HAS_CPUMASK;
+ }
if (option == 's' || option == 'S') {
CPU_CLR(ev->ev_cpu, &cpumask);
+ pmc_id_t saved_pmcid = ev->ev_pmcid;
+ ev->ev_pmcid = PMC_ID_INVALID;
pmcstat_clone_event_descriptor(ev, &cpumask, &args);
+ ev->ev_pmcid = saved_pmcid;
CPU_SET(ev->ev_cpu, &cpumask);
}
@@ -1050,17 +1112,8 @@
}
/* if we've been asked to process a log file, skip init */
- if ((args.pa_flags & FLAG_READ_LOGFILE) == 0) {
- if (pmc_init() < 0)
- err(EX_UNAVAILABLE,
- "ERROR: Initialization of the pmc(3) library failed"
- );
-
- if ((npmc = pmc_npmc(0)) < 0) /* assume all CPUs are identical */
- err(EX_OSERR,
-"ERROR: Cannot determine the number of PMCs on CPU %d",
- 0);
- }
+ if ((args.pa_flags & FLAG_READ_LOGFILE) == 0)
+ libpmc_initialize(&npmc);
/* Allocate a kqueue */
if ((pmcstat_kq = kqueue()) < 0)
@@ -1134,7 +1187,8 @@
*/
STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
- if (pmc_allocate(ev->ev_spec, ev->ev_mode,
+ if (ev->ev_pmcid == PMC_ID_INVALID &&
+ pmc_allocate(ev->ev_spec, ev->ev_mode,
ev->ev_flags, ev->ev_cpu, &ev->ev_pmcid,
ev->ev_count) < 0)
err(EX_OSERR,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 2, 12:39 AM (21 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14973925
Default Alt Text
D35342.diff (7 KB)
Attached To
Mode
D35342: System wide and NUMA domain wide counters support. PMC classes for ARM DMC-620 and CMN-600.
Attached
Detach File
Event Timeline
Log In to Comment