|
Packit Service |
a1973e |
.TH LIBPFM 3 "July , 2003" "" "Linux Programmer's Manual"
|
|
Packit Service |
a1973e |
.SH NAME
|
|
Packit Service |
a1973e |
pfm_dispatch_events \- determine PMC registers values for a set of events to measure
|
|
Packit Service |
a1973e |
.SH SYNOPSIS
|
|
Packit Service |
a1973e |
.nf
|
|
Packit Service |
a1973e |
.B #include <perfmon/pfmlib.h>
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.BI "int pfm_dispatch_events(pfmlib_input_param_t *"p ", void *" mod_in ", pfmlib_output_param_t *" q, "void *" mod_out ");"
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.SH DESCRIPTION
|
|
Packit Service |
a1973e |
This function is the central piece of the library. It is important to understand
|
|
Packit Service |
a1973e |
that the library does not effectively program the PMU, i.e., it does not make
|
|
Packit Service |
a1973e |
the operating system calls. The PMU is never actually accessed by the
|
|
Packit Service |
a1973e |
library. Instead, the library helps applications prepare the arguments to pass to
|
|
Packit Service |
a1973e |
the kernel. In particular, it sets up the values to program into the PMU
|
|
Packit Service |
a1973e |
configuration registers (PMC). The list of used data registers (PMD) is also
|
|
Packit Service |
a1973e |
returned.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The input argument are divided into two categories: the generic arguments in \fBp\fR
|
|
Packit Service |
a1973e |
and the optional PMU model specific arguments in \fBmod_in\fR.
|
|
Packit Service |
a1973e |
The same applies for the output arguments: \fBq\fR contains the generic
|
|
Packit Service |
a1973e |
output arguments and \fBmod_out\fR the optional PMU model specific arguments.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
An application describes what it wants to measure in the \fBin\fR and if it uses some model
|
|
Packit Service |
a1973e |
specific features, such as opcode matching on Itanium 2 processors, it must pass a pointer to the
|
|
Packit Service |
a1973e |
relevant model-specific input parameters in \fBmod_in\fR. The generic output parameters
|
|
Packit Service |
a1973e |
contains the register index and values for the PMC and PMD registers needed to
|
|
Packit Service |
a1973e |
make the measurement. The index mapping is guaranteed to match the mapping used
|
|
Packit Service |
a1973e |
by the Linux perfmon2 interface. In case the library is not used on this system,
|
|
Packit Service |
a1973e |
the hardware register addresses or indexes can also be retrieved from the output
|
|
Packit Service |
a1973e |
structure.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The \fBpfmlib_input_param_t\fR structure is defined as follows:
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.nf
|
|
Packit Service |
a1973e |
typedef struct
|
|
Packit Service |
a1973e |
int event;
|
|
Packit Service |
a1973e |
unsigned int plm;
|
|
Packit Service |
a1973e |
unsigned long flags;
|
|
Packit Service |
a1973e |
unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT];
|
|
Packit Service |
a1973e |
unsigned int num_masks;
|
|
Packit Service |
a1973e |
} pfmlib_event_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct {
|
|
Packit Service |
a1973e |
unsigned int pfp_event_count;
|
|
Packit Service |
a1973e |
unsigned int pfp_dfl_plm;
|
|
Packit Service |
a1973e |
unsigned int pfp_flags;
|
|
Packit Service |
a1973e |
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS];
|
|
Packit Service |
a1973e |
pfmlib_regmask_t pfp_unavail_pmcs;
|
|
Packit Service |
a1973e |
} pfmlib_input_param_t;
|
|
Packit Service |
a1973e |
.fi
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The structure mostly contains one table, called \fBpfp_events\fR which describes
|
|
Packit Service |
a1973e |
the events to be measured. The number of submitted events is indicated by
|
|
Packit Service |
a1973e |
\fBpfp_event_count\fR.
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
Each event is described in the \fBpfp_events\fR table by an opaque descriptor stored in
|
|
Packit Service |
a1973e |
the \fBevent\fR field. This descriptor is obtained with the \fBpfm_find_full_event()\fR
|
|
Packit Service |
a1973e |
or derivative functions. For some events, it may be necessary to specify at least one
|
|
Packit Service |
a1973e |
unit mask in the \fBunit_masks\fR table. A unit mask is yet another opaque descriptor
|
|
Packit Service |
a1973e |
obtained via the \fBpfm_find_event_mask()\fR or \fBpfm_find_full_event()\fR functions. Typically, if
|
|
Packit Service |
a1973e |
an event supports multiple unit masks, they can be combined in which case more than one
|
|
Packit Service |
a1973e |
entry in \fBunit_masks\fR must be specified. The actual number of unit mask descriptors
|
|
Packit Service |
a1973e |
passed must be indicated in \fBnum_masks\fR. When no unit mask is used, this
|
|
Packit Service |
a1973e |
field must be set to 0.
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
A privilege level mask for the event can be provided in \fBplm\fR. This is a bitmask where
|
|
Packit Service |
a1973e |
each bit indicates a privilege level at which to monitor, more than one bit can be set.
|
|
Packit Service |
a1973e |
The library supports up to four levels, but depending on the PMU model, some levels may not be
|
|
Packit Service |
a1973e |
available. The levels are as follows:
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFM_PLM0
|
|
Packit Service |
a1973e |
monitor at the privilege level 0. For many architectures, this means kernel level
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFM_PLM1
|
|
Packit Service |
a1973e |
monitor at privilege level 1
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFM_PLM2
|
|
Packit Service |
a1973e |
monitor at privilege level 2
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFM_PLM3
|
|
Packit Service |
a1973e |
monitor at the privilege level 3. For many architectures, this means user level
|
|
Packit Service |
a1973e |
.LP
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
Events with a \fBplm\fR value of 0 will use the default privilege level mask
|
|
Packit Service |
a1973e |
as indicated by \fBpfp_dfl_plm\fR which must be set to any combinations of
|
|
Packit Service |
a1973e |
values described above. It is illegal to have a value of 0 for this field.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The \fBpfp_flags\fR field contains a set of flags that affect the whole
|
|
Packit Service |
a1973e |
set of events to be monitored. The currently defined flags are:
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_PFP_SYSTEMWIDE
|
|
Packit Service |
a1973e |
indicates that the monitors are to be used in a system-wide monitoring session.
|
|
Packit Service |
a1973e |
This could influence the way the library sets up some register values.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.LP
|
|
Packit Service |
a1973e |
The \fBpfp_unavail_pmcs\fR bitmask can be used by applications to communicate
|
|
Packit Service |
a1973e |
to the library the list of PMC registers which are not available on the system.
|
|
Packit Service |
a1973e |
Some kernels may allocate certain PMC registers (and associated data registers)
|
|
Packit Service |
a1973e |
for other purposes. Those registers must not be used by the library
|
|
Packit Service |
a1973e |
otherwise the assignment of events to PMC registers may be rejected by the
|
|
Packit Service |
a1973e |
kernel. Applications must figure out which registers are available using
|
|
Packit Service |
a1973e |
a kernel interface at their disposal, the library does not provide this
|
|
Packit Service |
a1973e |
service. The library expect the restrictions to be expressed using the Linux
|
|
Packit Service |
a1973e |
perfmon2 PMC register mapping.
|
|
Packit Service |
a1973e |
.LP
|
|
Packit Service |
a1973e |
Refer to the PMU specific manual for a description of the model-specific
|
|
Packit Service |
a1973e |
input parameters to be passed in \fBmod_in\fR.
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
The generic output parameters are contained in the fBpfmlib_output_param_t\fR
|
|
Packit Service |
a1973e |
structure which is defined as:
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
.nf
|
|
Packit Service |
a1973e |
typedef struct {
|
|
Packit Service |
a1973e |
unsigned long long reg_value;
|
|
Packit Service |
a1973e |
unsigned int reg_num;
|
|
Packit Service |
a1973e |
unsigned long reg_addr;
|
|
Packit Service |
a1973e |
} pfmlib_reg_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct {
|
|
Packit Service |
a1973e |
unsigned int pfp_pmc_count;
|
|
Packit Service |
a1973e |
unsigned int pfp_pmd_count;
|
|
Packit Service |
a1973e |
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS];
|
|
Packit Service |
a1973e |
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS];
|
|
Packit Service |
a1973e |
} pfmlib_output_param_t;
|
|
Packit Service |
a1973e |
.fi
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The number of valid entries in the \fBpfp_pmcs\fR table is indicated by \fBpfp_pmc_count\fR.
|
|
Packit Service |
a1973e |
The number of valid entries in the \fBpfp_pmds\fR table is indicated by \fBpfp_pmd_count\fR.
|
|
Packit Service |
a1973e |
Each entry in both tables is of type \fBpfmlib_reg_t\fR.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
In the \fBpfp_pmcs\fR table, the \fBreg_num\fR contains the PMC register index (perfmon2 mapping),
|
|
Packit Service |
a1973e |
and the \fBreg_value\fR contains a 64-bit value to be used to program the PMC register.
|
|
Packit Service |
a1973e |
The \fBreg_addr\fR indicates the hardware address or index for the PMC register.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
In the \fBpfp_pmds\fR table, the \fBreg_num\fR contains the PMD register index
|
|
Packit Service |
a1973e |
(perfmon2 mapping). the \fBreg_value\fR is ignored. The \fBreg_addr\fR indicates the hardware
|
|
Packit Service |
a1973e |
address or index for the PMC register.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
Refer to the PMU specific manual for a description of the model-specific
|
|
Packit Service |
a1973e |
output parameters to be returned in \fBmod_out\fR.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
The current implementation of the \fBpfm_dispatch_events()\fR function completely overwrites
|
|
Packit Service |
a1973e |
the \fBpfmlib_output_param\fR structure. In other words, results do not accumulate
|
|
Packit Service |
a1973e |
into the \fBpfp_pmcs\fR table across multiple calls. Unused fields are
|
|
Packit Service |
a1973e |
guaranteed to be zeroed upon successful return.
|
|
Packit Service |
a1973e |
.sp
|
|
Packit Service |
a1973e |
Depending on the PMU model, there may not always be a one to one mapping between
|
|
Packit Service |
a1973e |
a PMC register and a data register. Register dependencies may be more intricate.
|
|
Packit Service |
a1973e |
However the \fBpfm_dispatch_events()\fR function guarantees certain ordering between the
|
|
Packit Service |
a1973e |
\fBpfp_pmcs\fR and \fBpfp_pmds\fR tables. In particular, it guarantees that
|
|
Packit Service |
a1973e |
the \fBpfp_pmds\fR table always starts with the counters corresponding, in
|
|
Packit Service |
a1973e |
the same order, to the events as provided in the \fBpfp_event\fR table on input.
|
|
Packit Service |
a1973e |
There is always one counter per event. Additional PMD registers, if any, come
|
|
Packit Service |
a1973e |
after.
|
|
Packit Service |
a1973e |
.SH EXAMPLE
|
|
Packit Service |
a1973e |
Here is a typical sequence using the perfmon2 interface:
|
|
Packit Service |
a1973e |
.nf
|
|
Packit Service |
a1973e |
#include <perfmon/pfmlib.h>
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
pfmlib_input_param_t inp;
|
|
Packit Service |
a1973e |
pfmlib_output_param_t outp;
|
|
Packit Service |
a1973e |
pfarg_ctx_t ctx;
|
|
Packit Service |
a1973e |
pfarg_pmd_t pd[1];
|
|
Packit Service |
a1973e |
pfarg_pmc_t pc[1];
|
|
Packit Service |
a1973e |
pfarg_load_t load_arg;
|
|
Packit Service |
a1973e |
int fd, i;
|
|
Packit Service |
a1973e |
int ret;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (pfm_initialize() != PFMLIB_SUCCESS) {
|
|
Packit Service |
a1973e |
fprintf(stderr, "can't initialize library\\n");
|
|
Packit Service |
a1973e |
exit(1);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
memset(&ctx,0, sizeof(ctx));
|
|
Packit Service |
a1973e |
memset(&inp,0, sizeof(inp));
|
|
Packit Service |
a1973e |
memset(&outp,0, sizeof(outp));
|
|
Packit Service |
a1973e |
memset(pd, 0, sizeof(pd));
|
|
Packit Service |
a1973e |
memset(pc, 0, sizeof(pc));
|
|
Packit Service |
a1973e |
memset(&load_arg, 0, sizeof(load_arg));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_cycle_event(&inp.pfp_events[0]);
|
|
Packit Service |
a1973e |
if (ret != PFMLIB_SUCCESS) {
|
|
Packit Service |
a1973e |
fprintf(stderr, "cannot find cycle event\\n");
|
|
Packit Service |
a1973e |
exit(1);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
inp.pfp_dfl_plm = PFM_PLM3;
|
|
Packit Service |
a1973e |
inp.pfp_event_count = 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_dispatch_events(&inp, NULL, &outp, NULL);
|
|
Packit Service |
a1973e |
if (ret != PFMLIB_SUCCESS) {
|
|
Packit Service |
a1973e |
fprintf(stderr, "cannot dispatch events: %s\\n", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
exit(1);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
/* propagate pmc value to perfmon2 structures */
|
|
Packit Service |
a1973e |
for(i=0; i < outp.pfp_pmc_count; i++) {
|
|
Packit Service |
a1973e |
pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
|
|
Packit Service |
a1973e |
pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
for(i=0; i < outp.pfp_pmd_count; i++) {
|
|
Packit Service |
a1973e |
pd[i].reg_num = outp.pfp_pmds[i].reg_num;
|
|
Packit Service |
a1973e |
pd[i].reg_value = 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
if (pfm_create_context(&ctx, NULL, 0) == -1 ) {
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
fd = ctx.ctx_fd;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (pfm_write_pmcs(fd, pc, outp.pfp_pmc_count) == -1) {
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (pfm_write_pmds(fd, pd, outp.pfp_pmd_count) == -1) {
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
load_arg.load_pid = getpid();
|
|
Packit Service |
a1973e |
if (pfm_load_context(fd, &load_arg) == -1) {
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pfm_start(fd, NULL);
|
|
Packit Service |
a1973e |
/* code to monitor */
|
|
Packit Service |
a1973e |
pfm_stop(fd);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (pfm_read_pmds(fd, pd, evt.pfp_event_count) == -1) {
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
printf("results: %llu\n", pd[0].reg_value);
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
close(fd);
|
|
Packit Service |
a1973e |
...
|
|
Packit Service |
a1973e |
.fi
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
.SH RETURN
|
|
Packit Service |
a1973e |
The function returns whether or not the call was successful.
|
|
Packit Service |
a1973e |
A return value of \fBPFMLIB_SUCCESS\fR indicates success,
|
|
Packit Service |
a1973e |
otherwise the value is the error code.
|
|
Packit Service |
a1973e |
.SH ERRORS
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_NOINIT
|
|
Packit Service |
a1973e |
The library has not been initialized properly.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_INVAL
|
|
Packit Service |
a1973e |
Some arguments were invalid. For instance the value of *count is zero.
|
|
Packit Service |
a1973e |
This can also be due to he content of the \fBpfmlib_param_t\fR structure.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_NOTFOUND
|
|
Packit Service |
a1973e |
No matching event was found.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_TOOMANY
|
|
Packit Service |
a1973e |
The number of events to monitor exceed the number of implemented counters.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_NOASSIGN
|
|
Packit Service |
a1973e |
The events cannot be dispatched to the PMC because events have conflicting constraints.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_MAGIC
|
|
Packit Service |
a1973e |
The model specific extension does not have the right magic number.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_FEATCOMB
|
|
Packit Service |
a1973e |
The set of events and features cannot be combined.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_EVTMANY
|
|
Packit Service |
a1973e |
An event has been supplied more than once and is causing resource (PMC) conflicts.
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_IRRINVAL
|
|
Packit Service |
a1973e |
Invalid code range restriction (Itanium, Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_IRRALIGN
|
|
Packit Service |
a1973e |
Code range has invalid alignment (Itanium, Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_IRRTOOMANY
|
|
Packit Service |
a1973e |
Cannot satisfy all the code ranges (Itanium, Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_DRRTOOMANY
|
|
Packit Service |
a1973e |
Cannot satisfy all the data ranges (Itanium, Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_DRRINVAL
|
|
Packit Service |
a1973e |
Invalid data range restriction (Itanium, Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_EVTSET
|
|
Packit Service |
a1973e |
Some events belong to incompatible sets (Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_EVTINCOMP
|
|
Packit Service |
a1973e |
Some events cannot be measured at the same time (Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_IRRTOOBIG
|
|
Packit Service |
a1973e |
Code range is too big (Itanium 2).
|
|
Packit Service |
a1973e |
.TP
|
|
Packit Service |
a1973e |
.B PFMLIB_ERR_UMASK
|
|
Packit Service |
a1973e |
Invalid or missing unit mask.
|
|
Packit Service |
a1973e |
.SH SEE ALSO
|
|
Packit Service |
a1973e |
libpfm_itanium(3), libpfm_itanium2(3), pfm_regmask_set(3), pfm_regmask_clr(3),
|
|
Packit Service |
a1973e |
pfm_find_event_code_mask(3)
|
|
Packit Service |
a1973e |
.SH AUTHOR
|
|
Packit Service |
a1973e |
Stephane Eranian <eranian@hpl.hp.com>
|
|
Packit Service |
a1973e |
.PP
|