Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162219184
D58029.id181268.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
D58029.id181268.diff
View Options
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
--- a/lib/libpmc/Makefile
+++ b/lib/libpmc/Makefile
@@ -77,6 +77,7 @@
MAN+= pmc.ibs.3
MAN+= pmc.ivybridge.3
MAN+= pmc.ivybridgexeon.3
+MAN+= pmc.rapl.3
MAN+= pmc.sandybridge.3
MAN+= pmc.sandybridgeuc.3
MAN+= pmc.sandybridgexeon.3
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -58,6 +58,8 @@
struct pmc_op_pmcallocate *_pmc_config);
static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
+static int rapl_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
#endif
#if defined(__arm__)
static int armv7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
@@ -191,6 +193,11 @@
__PMC_EV_ALIAS_TSC()
};
+static const struct pmc_event_descr rapl_event_table[] =
+{
+ __PMC_EV_RAPL()
+};
+
#undef PMC_CLASS_TABLE_DESC
#define PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR) \
static const struct pmc_class_descr NAME##_class_table_descr = \
@@ -208,6 +215,7 @@
PMC_CLASS_TABLE_DESC(k8, K8, k8, k8);
PMC_CLASS_TABLE_DESC(ibs, IBS, ibs, ibs);
PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
+PMC_CLASS_TABLE_DESC(rapl, RAPL, rapl, rapl);
#endif
#if defined(__arm__)
PMC_CLASS_TABLE_DESC(cortex_a8, ARMV7, cortex_a8, armv7);
@@ -879,6 +887,22 @@
return (0);
}
+
+static int
+rapl_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ if ((int)pe < PMC_EV_RAPL_FIRST || (int)pe > PMC_EV_RAPL_LAST)
+ return (-1);
+
+ /* RAPL events must be unqualified. */
+ if (ctrspec && *ctrspec != '\0')
+ return (-1);
+
+ pmc_config->pm_caps |= PMC_CAP_READ;
+
+ return (0);
+}
#endif
static struct pmc_event_alias generic_aliases[] = {
@@ -1435,6 +1459,10 @@
ev = tsc_event_table;
count = PMC_EVENT_TABLE_SIZE(tsc);
break;
+ case PMC_CLASS_RAPL:
+ ev = rapl_event_table;
+ count = PMC_EVENT_TABLE_SIZE(rapl);
+ break;
case PMC_CLASS_K8:
ev = k8_event_table;
count = PMC_EVENT_TABLE_SIZE(k8);
@@ -1643,6 +1671,10 @@
pmc_class_table[n++] = &tsc_class_table_descr;
break;
+ case PMC_CLASS_RAPL:
+ pmc_class_table[n++] = &rapl_class_table_descr;
+ break;
+
case PMC_CLASS_K8:
pmc_class_table[n++] = &k8_class_table_descr;
break;
@@ -1915,6 +1947,9 @@
} 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_RAPL_FIRST && pe <= PMC_EV_RAPL_LAST) {
+ ev = rapl_event_table;
+ evfence = rapl_event_table + PMC_EVENT_TABLE_SIZE(rapl);
} else if ((int)pe >= PMC_EV_SOFT_FIRST && (int)pe <= PMC_EV_SOFT_LAST) {
ev = soft_event_table;
evfence = soft_event_table + soft_event_info.pm_nevent;
diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3
--- a/lib/libpmc/pmc.3
+++ b/lib/libpmc/pmc.3
@@ -233,6 +233,12 @@
Programmable hardware counters present in
.Tn "AMD Athlon64"
CPUs.
+.It Li PMC_CLASS_RAPL
+RAPL energy counters present in
+.Tn AMD
+and
+.Tn Intel
+CPUs.
.It Li PMC_CLASS_TSC
The timestamp counter on i386 and amd64 architecture CPUs.
.It Li PMC_CLASS_ARMV7
@@ -498,6 +504,7 @@
.It Li PMC_CLASS_IAP Ta Xr pmc.atom 3 , Xr pmc.core 3 , Xr pmc.core2 3
.It Li PMC_CLASS_IBS Ta Xr pmc.ibs 3
.It Li PMC_CLASS_K8 Ta Xr pmc.amd 3
+.It Li PMC_CLASS_RAPL Ta Xr pmc.rapl 3
.It Li PMC_CLASS_TSC Ta Xr pmc.tsc 3
.El
.Ss Event Name Aliases
@@ -551,6 +558,7 @@
.Xr pmc.ibs 3 ,
.Xr pmc.ivybridge 3 ,
.Xr pmc.ivybridgexeon 3 ,
+.Xr pmc.rapl 3 ,
.Xr pmc.sandybridge 3 ,
.Xr pmc.sandybridgeuc 3 ,
.Xr pmc.sandybridgexeon 3 ,
diff --git a/lib/libpmc/pmc.rapl.3 b/lib/libpmc/pmc.rapl.3
new file mode 100644
--- /dev/null
+++ b/lib/libpmc/pmc.rapl.3
@@ -0,0 +1,138 @@
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2026 Advanced Micro Devices, Inc.
+.\"
+.Dd July 2, 2026
+.Dt PMC.RAPL 3
+.Os
+.Sh NAME
+.Nm pmc.rapl
+.Nd measurements using RAPL energy counters
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+.Tn AMD
+and
+.Tn Intel
+processors report cumulative energy consumption through the RAPL
+(Running Average Power Limit) machine specific registers.
+The
+.Li PMC_CLASS_RAPL
+class exposes these registers as read-only 64-bit counters that may
+only be allocated in system-wide counting mode
+.Pq Li PMC_MODE_SC .
+Counter values are cumulative energy in microjoules; the hardware
+energy unit, including the fixed DRAM unit used by
+.Tn Intel
+server processors, is applied in the kernel.
+.Pp
+A counter's accumulator is not reset when a PMC is allocated or
+released; it reflects energy consumed since the counters began
+accumulating and is reset only when the
+.Xr hwpmc 4
+module is unloaded.
+An individual reading is therefore meaningful only as a difference
+between two samples.
+.Pp
+The hardware counters are 32 bits wide and wrap frequently under load.
+The kernel folds them into 64-bit accumulators and samples every
+counter periodically while at least one RAPL PMC is allocated, so the
+exported values stay monotonic across counter wrap-around.
+.Pp
+RAPL events do not support further event qualifiers.
+.Ss Event Specifiers
+The following event names are supported:
+.Bl -tag -width indent
+.It Li rapl-energy-pkg
+Energy consumed by the processor package (socket) the counter is bound
+to.
+.It Li rapl-energy-cores
+On
+.Tn AMD
+processors, energy consumed by the physical core the counter is bound
+to.
+On
+.Tn Intel
+processors, energy consumed by the PP0 (all cores) power plane of the
+package, i.e. a package-scoped value.
+.It Li rapl-energy-dram
+Energy consumed by the DRAM domain of the package.
+Present only on
+.Tn Intel
+processors that implement the DRAM domain, typically server parts.
+.El
+.Ss Counter Scope
+RAPL counters measure package or core power domains, not individual
+CPUs: every CPU of a domain reads the same underlying counter.
+Consumers should bind one PMC per domain and must not sum readings
+from CPUs that share a domain.
+.Pp
+The class advertises the
+.Li PMC_CAP_DOMWIDE
+capability, which makes
+.Xr pmcstat 8
+allocate one counter per NUMA domain instead of one per CPU.
+NUMA domains follow the firmware memory policy and need not match
+packages, in either direction:
+.Bl -bullet
+.It
+With several NUMA domains per package (for example
+.Tn AMD
+NPS2/NPS4 or
+.Tn Intel
+Sub-NUMA Clustering),
+.Xr pmcstat 8
+allocates one counter per domain, so package-scoped counters within
+one package alias each other: each reading is correct on its own,
+but they must not be summed.
+.It
+With a single NUMA domain spanning several packages (for example
+.Tn AMD
+NPS0 memory interleaving, NUMA disabled in firmware, or a kernel
+built without NUMA support),
+.Xr pmcstat 8
+allocates only one counter, on the first configured CPU, and the
+remaining packages are silently not measured.
+.El
+.Pp
+For explicit placement, allocate one system-scope PMC per package
+with
+.Xr pmc_allocate 3 ,
+or give
+.Xr pmcstat 8
+one
+.Fl c Ar cpu
+and
+.Fl s Ar event
+pair per package, for example on a two-socket system whose second
+package starts at CPU 64:
+.Dl pmcstat -c 0 -s rapl-energy-pkg -c 64 -s rapl-energy-pkg
+A single
+.Fl c
+list naming several CPUs does not achieve this: for
+.Li PMC_CAP_DOMWIDE
+counters
+.Xr pmcstat 8
+honors only the first CPU of the list.
+.Ss Privilege
+Allocating a RAPL PMC always requires the
+.Li PRIV_PMC_SYSTEM
+privilege, regardless of the
+.Va security.bsd.unprivileged_syspmcs
+sysctl: fine-grained energy readings form a power side channel
+(PLATYPUS, CVE-2020-8694 and CVE-2020-12912).
+Unprivileged allocation requests fail with
+.Er EPERM .
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_allocate 3 ,
+.Xr pmc_read 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4 ,
+.Xr pmcstat 8
+.Sh HISTORY
+The RAPL PMC class first appeared in
+.Fx 16.0 .
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jul 12, 12:10 AM (19 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34893068
Default Alt Text
D58029.id181268.diff (7 KB)
Attached To
Mode
D58029: libpmc: userland support and pmc.rapl.3 for the RAPL class
Attached
Detach File
Event Timeline
Log In to Comment