Blame src/perfctr-2.7.x/linux/Documentation/perfctr/low-level-api.txt

Packit 577717
$Id: low-level-api.txt,v 1.1 2004/07/02 18:57:05 mikpe Exp $
Packit 577717
Packit 577717
PERFCTR LOW-LEVEL DRIVERS API
Packit 577717
=============================
Packit 577717
Packit 577717
This document describes the common low-level API.
Packit 577717
See low-level-$ARCH.txt for architecture-specific documentation.
Packit 577717
Packit 577717
General Model
Packit 577717
=============
Packit 577717
The model is that of a processor with:
Packit 577717
- A non-programmable clock-like counter, the "TSC".
Packit 577717
  The TSC frequency is assumed to be constant, but it is not
Packit 577717
  assumed to be identical to the core frequency.
Packit 577717
  The TSC may be absent.
Packit 577717
- A set of programmable counters, the "perfctrs" or "pmcs".
Packit 577717
  Control data may be per-counter, global, or both.
Packit 577717
  The counters are not assumed to be interchangeable.
Packit 577717
Packit 577717
  A normal counter that simply counts events is referred to
Packit 577717
  as an "accumulation-mode" or "a-mode" counter. Its total
Packit 577717
  count is computed by adding the counts for the individual
Packit 577717
  periods during which the counter is active. Two per-counter
Packit 577717
  state variables are used for this: "sum", which is the
Packit 577717
  total count up to but not including the current period,
Packit 577717
  and "start", which records the value of the hardware counter
Packit 577717
  at the start of the current period. At the end of a period,
Packit 577717
  the hardware counter's value is read again, and the increment
Packit 577717
  relative the start value is added to the sum. This strategy
Packit 577717
  is used because it avoids a number of hardware problems.
Packit 577717
Packit 577717
  A counter that has been programmed to generate an interrupt
Packit 577717
  on overflow is referred to as an "interrupt-mode" or "i-mode"
Packit 577717
  counter. I-mode counters are initialised to specific values,
Packit 577717
  and after overflowing are reset to their (re)start values.
Packit 577717
  The total event count is available just as for a-mode counters.
Packit 577717
Packit 577717
  The set of counters may be empty, in which case only the
Packit 577717
  TSC (which must be present) can be sampled.
Packit 577717
Packit 577717
Contents of <asm-$ARCH/perfctr.h>
Packit 577717
=================================
Packit 577717
Packit 577717
"struct perfctr_sum_ctrs"
Packit 577717
-------------------------
Packit 577717
struct perfctr_sum_ctrs {
Packit 577717
	unsigned long long tsc;
Packit 577717
	unsigned long long pmc[..];	/* one per counter */
Packit 577717
};
Packit 577717
Packit 577717
Architecture-specific container for counter values.
Packit 577717
Used in the kernel/user API, but not by the low-level drivers.
Packit 577717
Packit 577717
"struct perfctr_cpu_control"
Packit 577717
----------------------------
Packit 577717
This struct includes at least the following fields:
Packit 577717
Packit 577717
	unsigned int tsc_on;
Packit 577717
	unsigned int nractrs;		/* # of a-mode counters */
Packit 577717
	unsigned int nrictrs;		/* # of i-mode counters */
Packit 577717
	unsigned int pmc_map[..];	/* one per counter: virt-to-phys mapping */
Packit 577717
	unsigned int evntsel[..];	/* one per counter: hw control data */
Packit 577717
	int ireset[..];			/* one per counter: i-mode (re)start value */
Packit 577717
Packit 577717
Architecture-specific container for control data.
Packit 577717
Used both in the kernel/user API and by the low-level drivers
Packit 577717
(embedded in "struct perfctr_cpu_state").
Packit 577717
Packit 577717
"tsc_on" is non-zero if the TSC should be sampled.
Packit 577717
Packit 577717
"nractrs" is the number of a-mode counters, corresponding to
Packit 577717
elements 0..nractrs-1 in the per-counter arrays.
Packit 577717
Packit 577717
"nrictrs" is the number of i-mode counters, corresponding to
Packit 577717
elements nractrs..nractrs+nrictrs-1 in the per-counter arrays.
Packit 577717
Packit 577717
"nractrs+nrictrs" is the total number of counters to program
Packit 577717
and sample. A-mode and i-mode counters are separated in order
Packit 577717
to allow quick enumeration of either set, which is needed in
Packit 577717
some low-level driver operations.
Packit 577717
Packit 577717
"pmc_map[]" maps each counter to its corresponding hardware counter
Packit 577717
identification. No two counters may map to the same hardware counter.
Packit 577717
This mapping is present because the hardware may have asymmetric
Packit 577717
counters or other addressing quirks, which means that a counter's index
Packit 577717
may not suffice to address its hardware counter.
Packit 577717
Packit 577717
"evntsel[]" contains the per-counter control data. Architecture-specific
Packit 577717
global control data, if any, is placed in architecture-specific fields.
Packit 577717
Packit 577717
"ireset[]" contains the (re)start values for the i-mode counters.
Packit 577717
Only indices nractrs..nractrs+nrictrs-1 are used.
Packit 577717
Packit 577717
"struct perfctr_cpu_state"
Packit 577717
--------------------------
Packit 577717
This struct includes at least the following fields:
Packit 577717
Packit 577717
	unsigned int cstatus;
Packit 577717
	unsigned int tsc_start;
Packit 577717
	unsigned long long tsc_sum;
Packit 577717
	struct {
Packit 577717
		unsigned int map;
Packit 577717
		unsigned int start;
Packit 577717
		unsigned long long sum;
Packit 577717
	} pmc[..];	/* one per counter; the size is not part of the user ABI */
Packit 577717
#ifdef __KERNEL__
Packit 577717
	struct perfctr_cpu_control control;
Packit 577717
#endif
Packit 577717
Packit 577717
This type records the state and control data for a collection
Packit 577717
of counters. It is used by many low-level operations, and may
Packit 577717
be exported to user-space via mmap().
Packit 577717
Packit 577717
"cstatus" is a re-encoding of control.tsc_on/nractrs/nrictrs,
Packit 577717
used because it reduces overheads in key low-level operations.
Packit 577717
Operations on cstatus values include:
Packit 577717
- unsigned int perfctr_mk_cstatus(unsigned int tsc_on, unsigned int nractrs, unsigned int nrictrs);
Packit 577717
  Construct a cstatus value.
Packit 577717
- unsigned int perfctr_cstatus_enabled(unsigned int cstatus);
Packit 577717
  Check if any part (tsc_on, nractrs, nrictrs) of the cstatus is non-zero.
Packit 577717
- int perfctr_cstatus_has_tsc(unsigned int cstatus);
Packit 577717
  Check if the tsc_on part of the cstatus is non-zero.
Packit 577717
- unsigned int perfctr_cstatus_nrctrs(unsigned int cstatus);
Packit 577717
  Retrieve nractrs+nrictrs from the cstatus.
Packit 577717
- unsigned int perfctr_cstatus_has_ictrs(unsigned int cstatus);
Packit 577717
  Check if the nrictrs part of cstatus is non-zero.
Packit 577717
Packit 577717
"tsc_start" and "tsc_sum" record the state of the TSC.
Packit 577717
Packit 577717
"pmc[]" contains the per-counter state, in the "start" and "sum"
Packit 577717
fields. The "map" field contains the corresponding hardware counter
Packit 577717
identification, from the counter's entry in "control.pmc_map[]";
Packit 577717
it is copied into pmc[] to reduce overheads in key low-level operations.
Packit 577717
Packit 577717
"control" contains the control data which determines the
Packit 577717
behaviour of the counters.
Packit 577717
Packit 577717
User-space overflow signal handler items
Packit 577717
----------------------------------------
Packit 577717
After a counter has overflowed, a user-space signal handler may
Packit 577717
be invoked with a "struct siginfo" identifying the source of the
Packit 577717
signal and the set of overflown counters.
Packit 577717
Packit 577717
#define SI_PMC_OVF	..
Packit 577717
Packit 577717
Value to be stored in "si.si_code".
Packit 577717
Packit 577717
#define si_pmc_ovf_mask	..
Packit 577717
Packit 577717
Field in which to store a bit-mask of the overflown counters.
Packit 577717
Packit 577717
Kernel-internal API
Packit 577717
-------------------
Packit 577717
Packit 577717
/* Driver init/exit.
Packit 577717
   perfctr_cpu_init() performs hardware detection and may fail. */
Packit 577717
extern int perfctr_cpu_init(void);
Packit 577717
extern void perfctr_cpu_exit(void);
Packit 577717
Packit 577717
/* CPU type name. Set if perfctr_cpu_init() was successful. */
Packit 577717
extern char *perfctr_cpu_name;
Packit 577717
Packit 577717
/* Hardware reservation. A high-level driver must reserve the
Packit 577717
   hardware before it may use it, and release it afterwards.
Packit 577717
   "service" is a unique string identifying the high-level driver.
Packit 577717
   perfctr_cpu_reserve() returns NULL on success; if another
Packit 577717
   high-level driver has reserved the hardware, then that
Packit 577717
   driver's "service" string is returned. */
Packit 577717
extern const char *perfctr_cpu_reserve(const char *service);
Packit 577717
extern void perfctr_cpu_release(const char *service);
Packit 577717
Packit 577717
/* PRE: state has no running interrupt-mode counters.
Packit 577717
   Check that the new control data is valid.
Packit 577717
   Update the low-level driver's private control data.
Packit 577717
   is_global should be zero for per-process counters and non-zero
Packit 577717
   for global-mode counters.
Packit 577717
   Returns a negative error code if the control data is invalid. */
Packit 577717
extern int perfctr_cpu_update_control(struct perfctr_cpu_state *state, int is_global);
Packit 577717
Packit 577717
/* Stop i-mode counters. Update sums and start values.
Packit 577717
   Read a-mode counters. Subtract from start and accumulate into sums.
Packit 577717
   Must be called with preemption disabled. */
Packit 577717
extern void perfctr_cpu_suspend(struct perfctr_cpu_state *state);
Packit 577717
Packit 577717
/* Reset i-mode counters to their start values.
Packit 577717
   Write control registers.
Packit 577717
   Read a-mode counters and update their start values.
Packit 577717
   Must be called with preemption disabled. */
Packit 577717
extern void perfctr_cpu_resume(struct perfctr_cpu_state *state);
Packit 577717
Packit 577717
/* Perform an efficient combined suspend/resume operation.
Packit 577717
   Must be called with preemption disabled. */
Packit 577717
extern void perfctr_cpu_sample(struct perfctr_cpu_state *state);
Packit 577717
Packit 577717
/* The type of a perfctr overflow interrupt handler.
Packit 577717
   It will be called in IRQ context, with preemption disabled. */
Packit 577717
typedef void (*perfctr_ihandler_t)(unsigned long pc);
Packit 577717
Packit 577717
/* Install a perfctr overflow interrupt handler.
Packit 577717
   Should be called after perfctr_cpu_reserve() but before
Packit 577717
   any counter state has been activated. */
Packit 577717
extern void perfctr_cpu_set_ihandler(perfctr_ihandler_t);
Packit 577717
Packit 577717
/* PRE: The state has been suspended and sampled by perfctr_cpu_suspend().
Packit 577717
   Should be called from the high-level driver's perfctr_ihandler_t,
Packit 577717
   and preemption must not have been enabled.
Packit 577717
   Identify which counters have overflown, reset their start values
Packit 577717
   from ireset[], and perform any necessary hardware cleanup.
Packit 577717
   Returns a bit-mask of the overflown counters. */
Packit 577717
extern unsigned int perfctr_cpu_identify_overflow(struct perfctr_cpu_state*);
Packit 577717
Packit 577717
/* Call perfctr_cpu_ireload() just before perfctr_cpu_resume() to
Packit 577717
   bypass internal caching and force a reload of the i-mode pmcs.
Packit 577717
   This ensures that perfctr_cpu_identify_overflow()'s state changes
Packit 577717
   are propagated to the hardware. */
Packit 577717
extern void perfctr_cpu_ireload(struct perfctr_cpu_state*);