NAME
evcount
,
evcount_attach
,
evcount_detach
,
evcount_percpu
, evcount_inc
— generic interrupt and event
counter kernel API
SYNOPSIS
#include
<sys/evcount.h>
void
evcount_attach
(struct
evcount *ec, const char
*name, void
*data);
void
evcount_percpu
(struct
evcount *ec);
void
evcount_inc
(struct
evcount *ec);
void
evcount_detach
(struct
evcount *ec);
DESCRIPTION
The evcount
API provides an interface for
generic event and interrupt counting, whose statistics are made available to
machine-independent sysctl(2) nodes.
Overview
With evcount
, an architecture can collect
interrupt counting for any device. All registered counters will be made
available under the kern.evcount
sysctl(2)
node as a flat list. The following is a sample list of counters provided by
some common architectures:
See intro(4) for a list of devices for any of which
evcount
may track interrupt counting.
The systat(1) and vmstat(8) utilities can be used to view interrupts collected
by evcount
.
The API
The evcount structure has the following definition:
struct evcount { u_int64_t ec_count; /* main counter */ int ec_id; /* counter ID */ const char *ec_name; /* counter name */ void *ec_data; /* user data */ struct cpumem *ec_cpumem; /* per-cpu counter */ TAILQ_ENTRY(evcount) next; };
The
evcount_attach
(ec,
name, data) function adds the
given event counter to the system's counter list. name
provides the counter name, which is modeled after a device, such as
“clock” or “pciide0”. data
provides a chunk of data that will be made available through the
sysctl(2)
call.
The
evcount_percpu
(ec)
function configures ec with one counter for each CPU
in the system. It should be used when ec's
corresponding interrupt can occur simultaneously on multiple CPUs. It must
be called immediately after evcount_attach
() is
called for a given counter.
The
evcount_inc
(ec)
function increments the given counter.
The
evcount_detach
(ec)
function removes the given event counter ec from the
counter list.
EXAMPLES
The following is an outline of code that provides routines to
register and de-register interrupt handlers for devices, plugging the
counting of interrupts generated by them during system operation into the
evcount
framework.
#include <sys/evcount.h> #include <machine/intr.h> /* * machine/intr.h provides a structure, intrhand, which is * machine-dependent but is usually similar to this: * * struct intrhand { * int (*ih_fun)(void *); * void *ih_arg; * int ih_level; * struct intrhand *ih_next; * int ih_irq; * struct evcount ih_count; * } */ /* * Register an interrupt handler. */ void * intr_establish(void *lcv, int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg, char *name) { struct intrhand *ih, **p; /* * Allocate memory for the handler, sanity-check incoming * values (IRQ#, etc.), and link the handler into * machine-dependent data structures. */ /* * Fill out the handler. */ ih->ih_fun = ih_fun; ih->ih_arg = ih_arg; ih->ih_next = NULL; ih->ih_level = level; ih->ih_irq = irq; /* * Attach it. */ evcount_attach(&ih->ih_count, name, &ih->ih_irq); return (ih); } /* * Deregister an interrupt handler. */ void intr_disestablish(void *lcp, void *arg) { struct intrhand *ih = arg; /* * Sanity-check incoming values (IRQ, etc.) and remove * the interrupt handler from machine-dependent data * structures. */ evcount_detach(&ih->ih_count); /* * Free up memory and install a null interrupt handler. */ }
An interrupt handler for a device will be registered during
autoconf(9) with a call to the above
intr_establish
().
The main external interrupt handler, which handles all system
interrupts, will select the appropriate handler for the device that created
the interrupt when an interrupt is generated. In this case, the handler is
the routine assigned to ih_fun, and
evcount
will be made aware of interrupt
occurrence.
SEE ALSO
systat(1), sysctl(2), queue(3), intro(4), vmstat(8), autoconf(9), counters_alloc(9)
AUTHORS
The evcount
API was written by
Artur Grabowski and Aaron
Campbell for OpenBSD 3.6.