xref: /openbsd-src/share/man/man9/evcount.9 (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1.\"	$OpenBSD: evcount.9,v 1.3 2007/05/31 19:20:00 jmc Exp $
2.\" Written by Jared Yanovich
3.\" This file belongs to the public domain, 11/02/2004.
4.Dd $Mdocdate: May 31 2007 $
5.Dt EVCOUNT 9
6.Os
7.Sh NAME
8.Nm evcount ,
9.Nm evcount_attach ,
10.Nm evcount_detach
11.Nd generic interrupt and event counter kernel API
12.Sh SYNOPSIS
13.In sys/evcount.h
14.Ft void
15.Fn evcount_attach "struct evcount *ec" "const char *name" "void *data" \
16    "struct evcount *parent"
17.Ft void
18.Fn evcount_detach "struct evcount *ec"
19.Sh DESCRIPTION
20The
21.Nm
22API provides an interface for generic event and interrupt counting,
23whose statistics are made available to machine-independent
24.Xr sysctl 3
25nodes.
26.Ss Overview
27With
28.Nm ,
29an architecture can collect interrupt counting for any device and
30organize the counting hierarchy however it wants.
31All registered counters will be made available under the
32.Va kern.evcount
33.Xr sysctl 3
34node as a flat list.
35The following is a sample hierarchy for counters provided by some
36common architectures:
37.Pp
38.Bl -tag -width 8n -offset indent -compact
39.It clock
40Interrupt counter for the system clock
41.It stat
42Second-level interrupt decrementer counter
43.It rtc
44Real-time clock counter
45.It prof
46System profiler counter
47.It pciide0
48PCI IDE controller counter (see
49.Xr pciide 4 )
50.It uhci0
51USB 1.0 controller counter (see
52.Xr usb 4 )
53.El
54.Pp
55Event counters may be organized hierarchically, so a parent
56.Nm
57node that represents a bus may contain child nodes that represent
58devices attached to that bus.
59.Pp
60See
61.Xr intro 4
62for a list of devices for any of which
63.Nm
64may track interrupt counting.
65.Pp
66The
67.Xr systat 1
68and
69.Xr vmstat 8
70utilities can be used to view interrupts collected by
71.Nm .
72.Ss The API
73The
74.Vt evcount
75structure has the following definition:
76.Bd -literal -offset indent
77struct evcount {
78	u_int64_t		ec_count;	/* main counter */
79	int			ec_id;		/* counter ID */
80	const char		*ec_name;	/* counter name */
81	struct evcount		*ec_parent;	/* parent */
82	void			*ec_data;	/* user data */
83
84	TAILQ_ENTRY(evcount)	next;
85};
86.Ed
87.Pp
88The
89.Fn evcount_attach ec name data parent
90function inserts the given event counter
91.Fa ec
92into the given
93.Fa parent Ns 's
94list of counters.
95.Fa name
96provides the counter name, which is modeled after a
97device, such as
98.Dq clock
99or
100.Dq pciide0 .
101.Fa data
102provides a chunk of data that will be made available through the
103.Xr sysctl 3
104call.
105.Pp
106The
107.Fn evcount_detach ec
108function removes the given event counter
109.Fa ec
110from its parent.
111.Sh EXAMPLES
112The following is an outline of code that provides routines to register
113and de-register interrupt handlers for devices, plugging the counting of
114interrupts generated by them during system operation into the
115.Nm
116framework.
117.Bd -literal
118#include <sys/evcount.h>
119#include <machine/intr.h>
120
121/*
122 * machine/intr.h provides a structure, intrhand, which is
123 * machine-dependent but is usually similar to this:
124 *
125 *	struct intrhand {
126 *		int		(*ih_fun)(void *);
127 *		void		 *ih_arg;
128 *		int		  ih_level;
129 *		struct intrhand  *ih_next;
130 *		int		  ih_irq;
131 *		struct evcount    ih_count;
132 *	}
133 */
134
135/*
136 * Register an interrupt handler.
137 */
138void *
139intr_establish(void *lcv, int irq, int type, int level,
140	       int (*ih_fun)(void *), void *ih_arg, char *name)
141{
142	struct intrhand *ih, **p;
143
144	/*
145	 * Allocate memory for the handler, sanity-check incoming
146	 * values (IRQ#, etc.), and link the handler into
147	 * machine-dependent data structures.
148	 */
149
150	/*
151	 * Fill out the handler.
152	 */
153	ih->ih_fun = ih_fun;
154	ih->ih_arg = ih_arg;
155	ih->ih_next = NULL;
156	ih->ih_level = level;
157	ih->ih_irq = irq;
158
159	/*
160	 * Attach it under the root event counter, evcount_intr.
161	 */
162	evcount_attach(&ih->ih_count, name, (void *)&ih->ih_irq,
163	    &evcount_intr);
164
165	return (ih);
166}
167
168/*
169 * Deregister an interrupt handler.
170 */
171void
172intr_disestablish(void *lcp, void *arg)
173{
174	struct intrhand *ih = arg;
175
176	/*
177	 * Sanity-check incoming values (IRQ, etc.) and remove
178	 * the interrupt handler from machine-dependent data
179	 * structures.
180	 */
181
182	evcount_detach(&ih->ih_count);
183
184	/*
185	 * Free up memory and install a null interrupt handler.
186	 */
187}
188.Ed
189.Pp
190An interrupt handler for a device will be registered during
191.Xr autoconf 9
192with a call to the above
193.Fn intr_establish .
194.Pp
195The main external interrupt handler, which handles all system
196interrupts, will select the appropriate handler for the device
197that created the interrupt when an interrupt is generated.
198In this case, the handler is the routine assigned to
199.Va ih_fun ,
200and
201.Nm
202will be made aware of interrupt occurrence.
203.Sh SEE ALSO
204.Xr systat 1 ,
205.Xr queue 3 ,
206.Xr sysctl 3 ,
207.Xr intro 4 ,
208.Xr vmstat 8 ,
209.Xr autoconf 9
210.Sh AUTHORS
211The
212.Nm
213API was written by Artur Grabowski and Aaron Campbell for
214.Ox 3.6 .
215