- Add an overview of the pmc(3) API.
- Defer detailed descriptions of individual functions in the API to function-specific manual pages.
This commit is contained in:
parent
677d4530c2
commit
c89d1cf588
859
lib/libpmc/pmc.3
859
lib/libpmc/pmc.3
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2003-2006 Joseph Koshy. All rights reserved.
|
||||
.\" Copyright (c) 2003-2007 Joseph Koshy. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -23,302 +23,303 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 25, 2006
|
||||
.Dd November 25, 2007
|
||||
.Os
|
||||
.Dt PMC 3
|
||||
.Sh NAME
|
||||
.Nm pmc_allocate ,
|
||||
.Nm pmc_attach ,
|
||||
.Nm pmc_capabilities ,
|
||||
.Nm pmc_configure_logfile ,
|
||||
.Nm pmc_cpuinfo ,
|
||||
.Nm pmc_detach ,
|
||||
.Nm pmc_disable ,
|
||||
.Nm pmc_enable ,
|
||||
.Nm pmc_event_names_of_class ,
|
||||
.Nm pmc_flush_logfile ,
|
||||
.Nm pmc_get_driver_stats ,
|
||||
.Nm pmc_get_msr ,
|
||||
.Nm pmc_init ,
|
||||
.Nm pmc_name_of_capability ,
|
||||
.Nm pmc_name_of_class ,
|
||||
.Nm pmc_name_of_cputype ,
|
||||
.Nm pmc_name_of_event ,
|
||||
.Nm pmc_name_of_mode ,
|
||||
.Nm pmc_name_of_state ,
|
||||
.Nm pmc_ncpu ,
|
||||
.Nm pmc_npmc ,
|
||||
.Nm pmc_pmcinfo ,
|
||||
.Nm pmc_read ,
|
||||
.Nm pmc_release ,
|
||||
.Nm pmc_rw ,
|
||||
.Nm pmc_set ,
|
||||
.Nm pmc_start ,
|
||||
.Nm pmc_stop ,
|
||||
.Nm pmc_width ,
|
||||
.Nm pmc_write ,
|
||||
.Nm pmc_writelog
|
||||
.Nd programming API for using hardware performance monitoring counters
|
||||
.Nm pmc
|
||||
.Nd library for accessing hardware performance monitoring counters
|
||||
.Sh LIBRARY
|
||||
.Lb libpmc
|
||||
.Sh SYNOPSIS
|
||||
.In pmc.h
|
||||
.Ft int
|
||||
.Fo pmc_allocate
|
||||
.Fa "const char *eventspecifier"
|
||||
.Fa "enum pmc_mode mode"
|
||||
.Fa "uint32_t flags"
|
||||
.Fa "int cpu"
|
||||
.Fa "pmc_id_t *pmcid"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn pmc_attach "pmc_id_t pmcid" "pid_t pid"
|
||||
.Ft int
|
||||
.Fn pmc_capabilities "pmc_id_t pmc" "uint32_t *caps"
|
||||
.Ft int
|
||||
.Fn pmc_configure_logfile "int fd"
|
||||
.Ft int
|
||||
.Fn pmc_cpuinfo "const struct pmc_cpuinfo **cpu_info"
|
||||
.Ft int
|
||||
.Fn pmc_detach "pmc_id_t pmcid" "pid_t pid"
|
||||
.Ft int
|
||||
.Fn pmc_disable "int cpu" "int pmc"
|
||||
.Ft int
|
||||
.Fn pmc_enable "int cpu" "int pmc"
|
||||
.Ft int
|
||||
.Fo pmc_event_names_of_class
|
||||
.Fa "enum pmc_class cl"
|
||||
.Fa "const char ***eventnames"
|
||||
.Fa "int *nevents"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn pmc_flush_logfile void
|
||||
.Ft int
|
||||
.Fn pmc_get_driver_stats "struct pmc_driverstats *gms"
|
||||
.Ft int
|
||||
.Fn pmc_get_msr "pmc_id_t pmc" "uint32_t *msr"
|
||||
.Ft int
|
||||
.Fn pmc_init void
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_capability "enum pmc_caps pc"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_class "enum pmc_class pc"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_cputype "enum pmc_cputype ct"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_disposition "enum pmc_disp pd"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_event "enum pmc_event pe"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_mode "enum pmc_mode pm"
|
||||
.Ft "const char *"
|
||||
.Fn pmc_name_of_state "enum pmc_state ps"
|
||||
.Ft int
|
||||
.Fn pmc_ncpu void
|
||||
.Ft int
|
||||
.Fn pmc_npmc "int cpu"
|
||||
.Ft int
|
||||
.Fn pmc_pmcinfo "int cpu" "struct pmc_pmcinfo **pmc_info"
|
||||
.Ft int
|
||||
.Fn pmc_read "pmc_id_t pmc" "pmc_value_t *value"
|
||||
.Ft int
|
||||
.Fn pmc_release "pmc_id_t pmc"
|
||||
.Ft int
|
||||
.Fn pmc_rw "pmc_id_t pmc" "pmc_value_t newvalue" "pmc_value_t *oldvaluep"
|
||||
.Ft int
|
||||
.Fn pmc_set "pmc_id_t pmc" "pmc_value_t value"
|
||||
.Ft int
|
||||
.Fn pmc_start "pmc_id_t pmc"
|
||||
.Ft int
|
||||
.Fn pmc_stop "pmc_id_t pmc"
|
||||
.Ft int
|
||||
.Fn pmc_write "pmc_id_t pmc" "pmc_value_t value"
|
||||
.Ft int
|
||||
.Fn pmc_writelog "uint32_t userdata"
|
||||
.Ft int
|
||||
.Fn pmc_width "pmc_id_t pmc" "uint32_t *width"
|
||||
.Sh DESCRIPTION
|
||||
These functions implement a high-level library for using the
|
||||
system's hardware performance counters.
|
||||
.Pp
|
||||
PMCs are allocated using
|
||||
.Fn pmc_allocate ,
|
||||
released using
|
||||
.Fn pmc_release
|
||||
and read using
|
||||
.Fn pmc_read .
|
||||
Allocated PMCs may be started or stopped at any time using
|
||||
.Fn pmc_start
|
||||
and
|
||||
.Fn pmc_stop
|
||||
respectively.
|
||||
An allocated PMC may be of
|
||||
.Dq global
|
||||
scope, meaning that the PMC measures system-wide events, or
|
||||
.Dq process-private
|
||||
scope, meaning that the PMC only counts hardware events when
|
||||
the allocating process (or, optionally, its children)
|
||||
are active.
|
||||
.Pp
|
||||
PMCs may further be in
|
||||
.Dq "counting mode" ,
|
||||
or in
|
||||
.Dq "sampling mode" .
|
||||
Sampling mode PMCs deliver an interrupt to the CPU after
|
||||
a configured number of hardware events have been seen.
|
||||
A process-private sampling mode PMC will cause its owner
|
||||
process to get periodic
|
||||
.Dv SIGPROF
|
||||
interrupts, while a global sampling mode PMC is used to
|
||||
do system-wide statistical sampling (see
|
||||
.Xr hwpmc 4 ) .
|
||||
The sampling rate desired of a sampling-mode PMC is set using
|
||||
.Fn pmc_set .
|
||||
Counting mode PMCs do not interrupt the CPU; their values
|
||||
can be read using
|
||||
.Fn pmc_read .
|
||||
.Pp
|
||||
System-wide statistical sampling is configured by allocating
|
||||
at least one sampling mode PMC with
|
||||
global scope, and when a log file is configured using
|
||||
.Fn pmc_configure_logfile .
|
||||
The
|
||||
.Lb libpmc
|
||||
provides a programming interface that allows applications to use
|
||||
hardware performance counters to gather performance data about
|
||||
specific processes or for the system as a whole.
|
||||
The library is implemented using the lower-level facilities offered by
|
||||
the
|
||||
.Xr hwpmc 4
|
||||
driver manages system-wide statistical sampling; for more
|
||||
information please see
|
||||
.Xr hwpmc 4 .
|
||||
.Ss Application Programming Interface
|
||||
The function
|
||||
.Fn pmc_init
|
||||
initializes the
|
||||
.Nm pmc
|
||||
library.
|
||||
This function must be called first, before any of the other
|
||||
functions in the library.
|
||||
driver.
|
||||
.Ss Key Concepts
|
||||
Performance monitoring counters (PMCs) are represented by the library
|
||||
using a software abstraction.
|
||||
These
|
||||
.Dq abstract
|
||||
PMCs can have one two scopes:
|
||||
.Bl -bullet
|
||||
.It
|
||||
System scope.
|
||||
These PMCs measure events in a whole-system manner, i.e., independent
|
||||
of the currently executing thread.
|
||||
System scope PMCs are allocated on specific CPUs and do not
|
||||
migrate between CPUs.
|
||||
Non-privileged process are allowed to allocate system scope PMCs if the
|
||||
.Xr hwpmc 4
|
||||
sysctl tunable:
|
||||
.Va security.bsd.unprivileged_syspmcs
|
||||
is non-zero.
|
||||
.It
|
||||
Process scope.
|
||||
These PMCs only measure hardware events when the processes they are
|
||||
attached to are executing on a CPU.
|
||||
In an SMP system, process scope PMCs migrate between CPUs along with
|
||||
their target processes.
|
||||
.El
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_allocate
|
||||
allocates a counter that counts the events named by
|
||||
.Fa eventspecifier ,
|
||||
and writes the allocated counter ID to
|
||||
.Fa *pmcid .
|
||||
Argument
|
||||
.Fa eventspecifier
|
||||
comprises an PMC event name followed by an optional comma separated
|
||||
list of keywords and qualifiers.
|
||||
The allowed syntax for
|
||||
.Fa eventspecifier
|
||||
is processor architecture specific and is listed in section
|
||||
Orthogonal to PMC scope, PMCs may be allocated in one of two
|
||||
operational modes:
|
||||
.Bl -bullet
|
||||
.It
|
||||
Counting PMCs measure events according to their scope
|
||||
(system or process).
|
||||
The application needs to explicitly read these counters
|
||||
to retrieve their value.
|
||||
.It
|
||||
Sampling PMCs cause the CPU to be periodically interrupted
|
||||
and information about its state of execution to be collected.
|
||||
Sampling PMCs are used to profile specific processes and kernel
|
||||
threads or to profile the system as a whole.
|
||||
.El
|
||||
.Pp
|
||||
The scope and operational mode for a software PMC are specified at
|
||||
PMC allocation time.
|
||||
An application is allowed to allocate multiple PMCs subject
|
||||
to availability of hardware resources.
|
||||
.Pp
|
||||
The library uses human-readable strings to name the event being
|
||||
measured by hardware.
|
||||
The syntax used for specifying a hardware event along with additional
|
||||
event specific qualifiers (if any) is described in detail in section
|
||||
.Sx "EVENT SPECIFIERS"
|
||||
below.
|
||||
The desired PMC mode is specified by
|
||||
.Fa mode ,
|
||||
and any mode specific modifiers are specified using
|
||||
.Fa flags .
|
||||
The
|
||||
.Fa cpu
|
||||
argument is the value
|
||||
.Dv PMC_CPU_ANY ,
|
||||
or names the CPU the allocation is to be on.
|
||||
Requesting a specific CPU only makes sense for global PMCs;
|
||||
process-private PMC allocations should always specify
|
||||
.Dv PMC_CPU_ANY .
|
||||
.Pp
|
||||
By default, a PMC configured in process-virtual counting mode is set up
|
||||
to profile its owner process.
|
||||
The function
|
||||
.Fn pmc_attach
|
||||
may be used to attach the PMC to a different process.
|
||||
It
|
||||
needs to be called before the counter is first started
|
||||
with
|
||||
.Fn pmc_start .
|
||||
The function
|
||||
.Fn pmc_detach
|
||||
may be used to detach a PMC from a process it was attached to
|
||||
using a prior call to
|
||||
.Fn pmc_attach .
|
||||
PMCs are associated with the process that allocated them and
|
||||
will be automatically reclaimed by the system when the process exits.
|
||||
Additionally, process-scope PMCs have to be attached to one or more
|
||||
target processes before they can perform measurements.
|
||||
A process-scope PMC may be attached to those target processes
|
||||
that its owner process would otherwise be permitted to debug.
|
||||
An owner process may attach PMCs to itself allowing
|
||||
it to measure its own behavior.
|
||||
Additionally, on some machine architectures, such self-attached PMCs
|
||||
may be read cheaply using specialized instructions supported by the
|
||||
processor.
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_release
|
||||
releases a PMC previously allocated with
|
||||
.Fn pmc_allocate .
|
||||
This function call implicitly detaches the PMC from all its target
|
||||
processes.
|
||||
.Pp
|
||||
An allocated PMC may be started and stopped using
|
||||
.Fn pmc_start
|
||||
Certain kinds of PMCs require that a log file be configured before
|
||||
they may be started.
|
||||
These include:
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
System scope sampling PMCs.
|
||||
.It
|
||||
Process scope sampling PMCs.
|
||||
.It
|
||||
Process scope counting PMCs that have been configured to report PMC
|
||||
readings on process context switches or process exits.
|
||||
.El
|
||||
Upto one log file may be configured per owner process.
|
||||
Events logged to a log file may be subsequently analyzed using the
|
||||
.Xr pmclog 3
|
||||
family of functions.
|
||||
.Ss Supported CPUs
|
||||
The CPUs known to the PMC library are named by the
|
||||
.Vt "enum pmc_cputype"
|
||||
enumeration.
|
||||
Supported CPUs include:
|
||||
.Bl -tag -width PMC_CPU_INTEL_PIII -compact
|
||||
.It PMC_CPU_AMD_K7
|
||||
.Tn "AMD Athlon"
|
||||
CPUs.
|
||||
.It PMC_CPU_AMD_K8
|
||||
.Tn "AMD Athlon64"
|
||||
CPUs.
|
||||
.It PMC_CPU_INTEL_P6
|
||||
.Tn Intel
|
||||
.Tn "Pentium Pro"
|
||||
CPUs.
|
||||
.It PMC_CPU_INTEL_PII
|
||||
.Tn "Intel Pentium II"
|
||||
CPUs.
|
||||
.It PMC_CPU_INTEL_PIII
|
||||
.Tn "Intel Pentium III"
|
||||
CPUs.
|
||||
.It PMC_CPU_INTEL_PM
|
||||
.Tn "Intel Pentium M"
|
||||
CPUs.
|
||||
.It PMC_CPU_INTEL_PIV
|
||||
.Tn "Intel Pentium 4"
|
||||
CPUs.
|
||||
.El
|
||||
.Ss Supported PMCs
|
||||
PMC supported by this library are named by the
|
||||
.Vt enum pmc_class
|
||||
enumeration.
|
||||
Supported PMC kinds include:
|
||||
.Bl -tag -width PMC_CLASS_TSC -compact
|
||||
.It PMC_CLASS_TSC
|
||||
The timestamp counter on i386 and amd64 architecture CPUs.
|
||||
.It PMC_CLASS_K7
|
||||
Programmable hardware counters present in
|
||||
.Tn "AMD Athlon"
|
||||
CPUs.
|
||||
.It PMC_CLASS_K8
|
||||
Programmable hardware counters present in
|
||||
.Tn "AMD Athlon64"
|
||||
CPUs.
|
||||
.It PMC_CLASS_P6
|
||||
Programmable hardware counters present in
|
||||
.Tn Intel
|
||||
.Tn "Pentium Pro" ,
|
||||
.Tn "Pentium II" ,
|
||||
.Tn "Pentium III" ,
|
||||
.Tn "Celeron" ,
|
||||
and
|
||||
.Fn pmc_stop
|
||||
respectively.
|
||||
.Tn "Pentium M"
|
||||
CPUs.
|
||||
.It PMC_CLASS_P4
|
||||
Programmable hardware counters present in
|
||||
.Tn "Intel Pentium 4"
|
||||
CPUs.
|
||||
.El
|
||||
.Ss PMC Capabilities
|
||||
.Pp
|
||||
The current value of a PMC may be read with
|
||||
.Fn pmc_read
|
||||
and written using
|
||||
.Fn pmc_write ,
|
||||
provided the underlying hardware supports these operations on
|
||||
the allocated PMC.
|
||||
The read and write operation may be combined using
|
||||
.Fn pmc_rw .
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_capabilities
|
||||
sets argument
|
||||
.Fa caps
|
||||
to a bitmask of capabilities supported by the PMC denoted by
|
||||
argument
|
||||
Capabilities of performance monitoring hardware are denoted using
|
||||
the
|
||||
.Vt "enum pmc_caps"
|
||||
enumeration.
|
||||
Supported capabilities include:
|
||||
.Bl -tag -width "PMC_CAP_INTERRUPT" -compact
|
||||
.It PMC_CAP_EDGE
|
||||
The ability to count negated to asserted transitions of the hardware
|
||||
conditions being probed for.
|
||||
.It PMC_CAP_INTERRUPT
|
||||
The ability to interrupt the CPU.
|
||||
.It PMC_CAP_INVERT
|
||||
The ability to invert the sense of the hardware conditions being
|
||||
measured.
|
||||
.It PMC_CAP_READ
|
||||
PMC hardware allows the CPU to read performance counters.
|
||||
.It PMC_CAP_QUALIFIER
|
||||
The hardware allows monitored to be further qualified in some
|
||||
system dependent way.
|
||||
.It PMC_CAP_SYSTEM
|
||||
The ability to restrict counting of hardware events to when the CPU is
|
||||
running privileged code.
|
||||
.It PMC_CAP_THRESHOLD
|
||||
The ability to ignore simultaneous hardware events below a
|
||||
programmable threshold.
|
||||
.It PMC_CAP_USER
|
||||
The ability to restrict counting of hardware events to those when the
|
||||
CPU is running unprivileged code.
|
||||
.It PMC_CAP_WRITE
|
||||
PMC hardware allows CPUs write to counters.
|
||||
.El
|
||||
.Ss Functional Grouping
|
||||
This section contains a brief overview of the available functionality
|
||||
in the PMC library.
|
||||
Each function listed here is described further in its own manual page.
|
||||
.Bl -tag -width indent
|
||||
.It Administration
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_disable , Fn pmc_enable
|
||||
Administratively disable (enable) specific performance monitoring
|
||||
counter hardware.
|
||||
Counters that are disabled will not be available to applications to
|
||||
use.
|
||||
.El
|
||||
.It "Convenience Functions"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_event_names_of_class
|
||||
Returns a list of event names supported by a given PMC type.
|
||||
.It Fn pmc_name_of_capability
|
||||
Convert a
|
||||
.Dv PMC_CAP_*
|
||||
flag to a human-readable string.
|
||||
.It Fn pmc_name_of_class
|
||||
Convert a
|
||||
.Dv PMC_CLASS_*
|
||||
constant to a human-readable string.
|
||||
.It Fn pmc_name_of_cputype
|
||||
Return a human-readable name for a CPU type.
|
||||
.It Fn pmc_name_of_disposition
|
||||
Return a human-readable string describing a PMC's disposition.
|
||||
.It Fn pmc_name_of_event
|
||||
Convert a numeric event code to a human-readable string.
|
||||
.It Fn pmc_name_of_mode
|
||||
Convert a
|
||||
.Dv PMC_MODE_*
|
||||
constant to a human-readable name.
|
||||
.It Fn pmc_name_of_state
|
||||
Return a human-readable string describing a PMC's current state.
|
||||
.El
|
||||
.It "Library Initialization"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_init
|
||||
Initialize the library.
|
||||
This function must be called before any other library function.
|
||||
.El
|
||||
.It "Log File Handling"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_configure_logfile
|
||||
Configure a log file for
|
||||
.Xr hwpmc 4
|
||||
to write logged events to.
|
||||
.It Fn pmc_flush_logfile
|
||||
Flush all pending log data in
|
||||
.Xr hwpmc 4 Ns Ap s
|
||||
buffers.
|
||||
.It Fn pmc_writelog
|
||||
Append arbitrary user data to the current log file.
|
||||
.El
|
||||
.It "PMC Management"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_allocate , Fn pmc_release
|
||||
Allocate (free) a PMC.
|
||||
.It Fn pmc_attach , Fn pmc_detach
|
||||
Attach (detach) a process scope PMC to a target.
|
||||
.It Fn pmc_read , Fn pmc_write , Fn pmc_rw
|
||||
Read (write) a value from (to) a PMC.
|
||||
.It Fn pmc_start , Fn pmc_stop
|
||||
Start (stop) a software PMC.
|
||||
.It Fn pmc_set
|
||||
Set the reload value for a sampling PMC.
|
||||
.El
|
||||
.It "Queries"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_capabilities
|
||||
Retrieve the capabilities for a given PMC.
|
||||
.It Fn pmc_cpuinfo
|
||||
Retrieve information about the CPUs and PMC hardware present in the
|
||||
system.
|
||||
.It Fn pmc_get_driver_stats
|
||||
Retrieve statistics maintained by
|
||||
.Xr hwpmc 4 .
|
||||
.It Fn pmc_ncpu
|
||||
Determine the number of CPUs in the system.
|
||||
.It Fn pmc_npmc
|
||||
Return the number of hardware PMCs present in a given CPU.
|
||||
.It Fn pmc_pmcinfo
|
||||
Return information about the state of a given CPU's PMCs.
|
||||
.It Fn pmc_width
|
||||
Determine the width of a hardware counter in bits.
|
||||
.El
|
||||
.It "x86 Architecture Specific API"
|
||||
.Bl -tag -compact
|
||||
.It Fn pmc_get_msr
|
||||
Returns the processor model specific register number
|
||||
associated with
|
||||
.Fa pmc .
|
||||
The function
|
||||
.Fn pmc_width
|
||||
sets argument
|
||||
.Fa width
|
||||
to the width of the PMC denoted by argument
|
||||
.Fa pmc .
|
||||
.Pp
|
||||
The
|
||||
.Fn pmc_configure_logfile
|
||||
function causes the
|
||||
.Xr hwpmc 4
|
||||
driver to log performance data to file corresponding
|
||||
to the process' file handle
|
||||
.Fa fd .
|
||||
If argument
|
||||
.Fa fd
|
||||
is \-1, then any previously configured logging is reset
|
||||
and all data queued to be written are discarded.
|
||||
.Pp
|
||||
The
|
||||
.Fn pmc_flush_logfile
|
||||
function will send all data queued inside the
|
||||
.Xr hwpmc 4
|
||||
driver to the configured log file before returning.
|
||||
The
|
||||
.Fn pmc_writelog
|
||||
function will append a log entry containing the argument
|
||||
.Fa userdata
|
||||
to the log file.
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_set
|
||||
configures a sampling PMC
|
||||
.Fa pmc
|
||||
to interrupt every
|
||||
.Fa value
|
||||
events.
|
||||
For counting PMCs,
|
||||
.Fn pmc_set
|
||||
sets the initial value of the PMC to
|
||||
.Fa value .
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_get_driver_statistics
|
||||
copies a snapshot of the usage statistics maintained by
|
||||
.Xr hwpmc 4
|
||||
into the memory area pointed to by argument
|
||||
.Fa gms .
|
||||
Applications may then use the x86
|
||||
.Ic RDPMC
|
||||
instruction to directly read the contents of the PMC.
|
||||
.El
|
||||
.El
|
||||
.Ss Signal Handling Requirements
|
||||
Applications using PMCs are required to handle the following signals:
|
||||
.Bl -tag -width indent
|
||||
.Bl -tag -width ".Dv SIGBUS"
|
||||
.It Dv SIGBUS
|
||||
When the
|
||||
.Xr hwpmc 4
|
||||
@ -344,88 +345,50 @@ This error may be retrieved by a subsequent call to
|
||||
.Fn pmc_flush_logfile .
|
||||
.El
|
||||
.El
|
||||
.Ss Convenience Functions
|
||||
The function
|
||||
.Fn pmc_ncpu
|
||||
returns the number of CPUs present in the system.
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_npmc
|
||||
returns the number of PMCs supported on CPU
|
||||
.Fa cpu .
|
||||
The function
|
||||
.Fn pmc_cpuinfo
|
||||
sets argument
|
||||
.Fa cpu_info
|
||||
to point to an internal structure with information about the system's CPUs.
|
||||
The caller should not
|
||||
.Fn free
|
||||
this pointer value.
|
||||
Function
|
||||
.Fn pmc_pmcinfo
|
||||
returns information about the current state of CPU
|
||||
.Fa cpu Ns 's
|
||||
PMCs.
|
||||
This function sets argument
|
||||
.Fa *pmc_info
|
||||
to point to a memory area allocated with
|
||||
.Xr calloc 3 .
|
||||
The caller is expected to
|
||||
.Fn free
|
||||
the area when done.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn pmc_name_of_capability ,
|
||||
.Fn pmc_name_of_class ,
|
||||
.Fn pmc_name_of_cputype ,
|
||||
.Fn pmc_name_of_disposition ,
|
||||
.Fn pmc_name_of_event ,
|
||||
.Fn pmc_name_of_mode
|
||||
and
|
||||
.Fn pmc_name_of_state
|
||||
are useful for code wanting to print error messages.
|
||||
They return
|
||||
.Vt "const char *"
|
||||
pointers to human-readable representations of their arguments.
|
||||
These return values should not be freed using
|
||||
.Xr free 3 .
|
||||
.Pp
|
||||
The function
|
||||
.Fn pmc_event_names_of_class
|
||||
returns a list of event names supported by a given PMC class
|
||||
.Fa cl .
|
||||
On successful return, an array of
|
||||
.Vt "const char *"
|
||||
pointers to the names of valid events supported by class
|
||||
.Fa cl
|
||||
is allocated by the library using
|
||||
.Xr malloc 3 ,
|
||||
and a pointer to this array is returned in the location pointed to by
|
||||
.Fa eventnames .
|
||||
The number of pointers allocated is returned in the location pointed
|
||||
to by
|
||||
.Fa nevents .
|
||||
.Ss Administration
|
||||
Individual PMCs may be enabled or disabled on a given CPU using
|
||||
.Fn pmc_enable
|
||||
and
|
||||
.Fn pmc_disable
|
||||
respectively.
|
||||
For these functions,
|
||||
.Fa cpu
|
||||
is the CPU number, and
|
||||
.Fa pmc
|
||||
is the index of the PMC to be operated on.
|
||||
Only the super-user is allowed to enable and disable PMCs.
|
||||
.Ss x86 Architecture Specific API
|
||||
The
|
||||
.Fn pmc_get_msr
|
||||
function returns the processor model specific register number
|
||||
associated with
|
||||
.Fa pmc .
|
||||
Applications may use the x86
|
||||
.Ic RDPMC
|
||||
instruction to directly read the contents of the PMC.
|
||||
.Ss Typical Program Flow
|
||||
.Bl -enum
|
||||
.It
|
||||
An application would first invoke function
|
||||
.Fn pmc_init
|
||||
to allow the library to initialize itself.
|
||||
.It
|
||||
Signal handling would then be set up.
|
||||
.It
|
||||
Next the application would allocate the PMCs it desires using function
|
||||
.Fn pmc_allocate .
|
||||
.It
|
||||
Initial values for PMCs may be set using function
|
||||
.Fn pmc_set .
|
||||
.It
|
||||
If a log file is necessary for the PMCs to work, it would
|
||||
be configured using function
|
||||
.Fn pmc_configure_logfile .
|
||||
.It
|
||||
Process scope PMCs would then be attached to their target processes
|
||||
using function
|
||||
.Fn pmc_attach .
|
||||
.It
|
||||
The PMCs would then be started using function
|
||||
.Fn pmc_start .
|
||||
.It
|
||||
Once started, the values of counting PMCs may be read using function
|
||||
.Fn pmc_start .
|
||||
For PMCs that write events to the log file, this logged data would be
|
||||
read and parsed using the
|
||||
.Xr pmclog 3
|
||||
family of functions.
|
||||
.It
|
||||
PMCs are stopped using function
|
||||
.Fn pmc_stop ,
|
||||
and process scope PMCs are detached from their targets using
|
||||
function
|
||||
.Fn pmc_detach .
|
||||
.It
|
||||
Before the process exits, its may release its PMCs using function
|
||||
.Fn pmc_release .
|
||||
Any configured log file may be closed using function
|
||||
.Fn pmc_configure_logfile .
|
||||
.El
|
||||
.Sh EVENT SPECIFIERS
|
||||
Event specifiers are strings comprising of an event name, followed by
|
||||
optional parameters modifying the semantics of the hardware event
|
||||
@ -3226,51 +3189,7 @@ to name and allocate all the resources needed for a
|
||||
cascaded event counter pair in a single operation.
|
||||
.Ss "Precise Event Based Sampling"
|
||||
Support for precise event based sampling is currently
|
||||
unimplemented in
|
||||
.Xr hwpmc 4 .
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
On the i386 architecture,
|
||||
.Fx
|
||||
has historically allowed the use of the RDTSC instruction from
|
||||
user-mode (i.e., at a processor CPL of 3) by any process.
|
||||
This behaviour is preserved by
|
||||
.Xr hwpmc 4 .
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn pmc_name_of_capability ,
|
||||
.Fn pmc_name_of_class ,
|
||||
.Fn pmc_name_of_cputype ,
|
||||
.Fn pmc_name_of_disposition ,
|
||||
.Fn pmc_name_of_event ,
|
||||
.Fn pmc_name_of_mode ,
|
||||
and
|
||||
.Fn pmc_name_of_state
|
||||
functions return a pointer to the human readable form of their argument.
|
||||
These pointers may point to statically allocated storage and must
|
||||
not be passed to
|
||||
.Fn free .
|
||||
In case of an error, these functions return
|
||||
.Dv NULL
|
||||
and set the global variable
|
||||
.Va errno .
|
||||
.Pp
|
||||
The functions
|
||||
.Fn pmc_ncpu
|
||||
and
|
||||
.Fn pmc_npmc
|
||||
return the number of CPUs and number of PMCs configured respectively;
|
||||
in case of an error they return the value
|
||||
\-1
|
||||
and set the global variable
|
||||
.Va errno .
|
||||
.Pp
|
||||
All other functions return the value
|
||||
0
|
||||
if successful; otherwise the value
|
||||
\-1
|
||||
is returned and the global variable
|
||||
.Va errno
|
||||
is set to indicate the error.
|
||||
unimplemented.
|
||||
.Sh COMPATIBILITY
|
||||
The interface between the
|
||||
.Nm pmc
|
||||
@ -3288,123 +3207,7 @@ The
|
||||
.Nm pmc
|
||||
API is
|
||||
.Ud
|
||||
.Sh ERRORS
|
||||
A call to
|
||||
.Fn pmc_init
|
||||
may fail with the following errors in addition to those returned by
|
||||
.Xr modfind 2 ,
|
||||
.Xr modstat 2
|
||||
and
|
||||
.Xr hwpmc 4 :
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er ENXIO
|
||||
An unknown CPU type was encountered during initialization.
|
||||
.It Bq Er EPROGMISMATCH
|
||||
The version number of the
|
||||
.Xr hwpmc 4
|
||||
kernel module did not match that compiled into the
|
||||
.Nm pmc
|
||||
library.
|
||||
.El
|
||||
.Pp
|
||||
A call to
|
||||
.Fn pmc_capabilities ,
|
||||
.Fn pmc_name_of_capability ,
|
||||
.Fn pmc_name_of_disposition ,
|
||||
.Fn pmc_name_of_state ,
|
||||
.Fn pmc_name_of_event ,
|
||||
.Fn pmc_name_of_mode
|
||||
.Fn pmc_name_of_class
|
||||
and
|
||||
.Fn pmc_width
|
||||
may fail with the following error:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
An invalid argument was passed to the function.
|
||||
.El
|
||||
.Pp
|
||||
A call to
|
||||
.Fn pmc_cpuinfo
|
||||
or
|
||||
.Fn pmc_ncpu
|
||||
may fail with the following error:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er ENXIO
|
||||
The
|
||||
.Nm pmc
|
||||
has not been initialized.
|
||||
.El
|
||||
.Pp
|
||||
A call to
|
||||
.Fn pmc_npmc
|
||||
may fail with the following errors:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The argument passed in was out of range.
|
||||
.It Bq Er ENXIO
|
||||
The
|
||||
.Nm pmc
|
||||
library has not been initialized.
|
||||
.El
|
||||
.Pp
|
||||
A call to
|
||||
.Fn pmc_pmcinfo
|
||||
may fail with the following errors, in addition to those returned by
|
||||
.Xr hwpmc 4 :
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er ENXIO
|
||||
The
|
||||
.Nm pmc
|
||||
library is not yet initialized.
|
||||
.El
|
||||
.Pp
|
||||
A call to
|
||||
.Fn pmc_allocate
|
||||
may fail with the following errors, in addition to those returned by
|
||||
.Xr hwpmc 4 :
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa mode
|
||||
argument passed in had an illegal value, or the event specification
|
||||
.Fa ctrspec
|
||||
was unrecognized for this CPU type.
|
||||
.El
|
||||
.Pp
|
||||
Calls to
|
||||
.Fn pmc_attach ,
|
||||
.Fn pmc_configure_logfile ,
|
||||
.Fn pmc_detach ,
|
||||
.Fn pmc_disable ,
|
||||
.Fn pmc_enable ,
|
||||
.Fn pmc_get_driver_stats ,
|
||||
.Fn pmc_get_msr ,
|
||||
.Fn pmc_read ,
|
||||
.Fn pmc_release ,
|
||||
.Fn pmc_rw ,
|
||||
.Fn pmc_set ,
|
||||
.Fn pmc_start ,
|
||||
.Fn pmc_stop ,
|
||||
.Fn pmc_write ,
|
||||
and
|
||||
.Fn pmc_writelog
|
||||
may fail with the errors described in
|
||||
.Xr hwpmc 4 .
|
||||
.Pp
|
||||
If a log file was configured using
|
||||
.Fn pmc_configure_logfile
|
||||
and the
|
||||
.Xr hwpmc 4
|
||||
driver encountered an error while logging data to it, then
|
||||
logging will be stopped and a subsequent call to
|
||||
.Fn pmc_flush_logfile
|
||||
will fail with the error code seen by the
|
||||
.Xr hwpmc 4
|
||||
driver.
|
||||
.Sh SEE ALSO
|
||||
.Xr modfind 2 ,
|
||||
.Xr modstat 2 ,
|
||||
.Xr calloc 3 ,
|
||||
.Xr pmclog 3 ,
|
||||
.Xr hwpmc 4 ,
|
||||
.Xr pmccontrol 8 ,
|
||||
@ -3414,13 +3217,9 @@ The
|
||||
.Nm pmc
|
||||
library first appeared in
|
||||
.Fx 6.0 .
|
||||
.Sh BUGS
|
||||
The information returned by
|
||||
.Fn pmc_cpuinfo ,
|
||||
.Fn pmc_ncpu
|
||||
and possibly
|
||||
.Fn pmc_npmc
|
||||
should really be available all the time, through a better designed
|
||||
interface and not just when
|
||||
.Xr hwpmc 4
|
||||
is present in the kernel.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Lb libpmc
|
||||
library was written by
|
||||
.An "Joseph Koshy"
|
||||
.Aq jkoshy@FreeBSD.org .
|
||||
|
Loading…
x
Reference in New Issue
Block a user