No empty .Rs/.Re
[netbsd-mini2440.git] / share / man / man9 / evcnt.9
blobdf593a2de6712d93f12936d254639a0b7b9954d6
1 .\" $NetBSD: evcnt.9,v 1.16 2007/12/20 03:21:47 uebayasi Exp $
2 .\"
3 .\" Copyright (c) 2000 Christopher G. Demetriou
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\"    must display the following acknowledgement:
16 .\"          This product includes software developed for the
17 .\"          NetBSD Project.  See http://www.NetBSD.org/ for
18 .\"          information about NetBSD.
19 .\" 4. The name of the author may not be used to endorse or promote products
20 .\"    derived from this software without specific prior written permission.
21 .\"
22 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 .\"
33 .\" --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
34 .\"
35 .Dd January 11, 2005
36 .Dt EVCNT 9
37 .Os
38 .Sh NAME
39 .Nm evcnt ,
40 .Nm evcnt_attach_dynamic ,
41 .Nm evcnt_attach_static ,
42 .Nm evcnt_detach
43 .Nd generic event counter framework
44 .Sh SYNOPSIS
45 .In sys/evcnt.h
46 .Ft void
47 .Fn evcnt_attach_dynamic "struct evcnt *ev" "int type" "const struct evcnt *parent" "const char *group" "const char *name"
48 .Ft void
49 .Fn evcnt_attach_static "struct evcnt *ev"
50 .Ft void
51 .Fn evcnt_detach "struct evcnt *ev"
52 .Sh DESCRIPTION
53 The
54 .Nx
55 generic event counter framework is designed to provide a flexible and
56 hierarchical event counting facility, which is useful for tracking
57 system events (including device interrupts).
58 .Pp
59 The fundamental component of this framework is the
60 .Nm evcnt
61 structure.
62 Its user-accessible fields are:
63 .Bd -literal
64 struct evcnt {
65         uint64_t        ev_count;       /* how many have occurred */
66         TAILQ_ENTRY(evcnt) ev_list;     /* entry on list of all counters */
67         unsigned char   ev_type;        /* counter type; see below */
68         unsigned char   ev_grouplen;    /* 'group' len, excluding NUL */
69         unsigned char   ev_namelen;     /* 'name' len, excluding NUL */
70         const struct evcnt *ev_parent;  /* parent, for hierarchical ctrs */
71         const char      *ev_group;      /* name of group */
72         const char      *ev_name;       /* name of specific event */
74 .Ed
75 .Pp
76 The system maintains a global linked list of all active event counters.
77 This list, called
78 .Nm allevents ,
79 may grow or shrink over time as event counters are dynamically
80 added to and removed from the system.
81 .Pp
82 Each event counter is marked (in the
83 .Fa ev_type
84 field) with the type of event being counted.
85 The following types are currently defined:
86 .Bl -tag -offset indent -width EVCNT_TYPE_MISC -compact
87 .It Ev EVCNT_TYPE_MISC
88 Miscellaneous; doesn't fit into one of the other types.
89 .It Ev EVCNT_TYPE_INTR
90 Interrupt counter, reported by
91 .Ic vmstat -i .
92 .It Ev EVCNT_TYPE_TRAP
93 Processor trap style events.
94 .El
95 .Pp
96 Each event counter also has a group name
97 .Pq Fa ev_group
98 and
99 an event name
100 .Pq Fa ev_name
101 which are used to identify the counter.
102 The group name may be shared by a set of counters.
103 For example, device interrupt counters would use the name of the
104 device whose interrupts are being counted as the group name.
105 The counter
106 name is meant to distinguish the counter from others in its group
107 (and need not be unique across groups).
108 Both names should be understandable by users, since they are printed
109 by commands like
110 .Xr vmstat 1 .
111 The constant
112 .Dv EVCNT_STRING_MAX
113 is defined to be the maximum group or event name length in
114 bytes (including the trailing
115 .Dv NUL ) .
116 In the current implementation it is 256.
118 To support hierarchical tracking of events, each event counter can
119 name a
120 .Dq parent
121 event counter.
122 For instance, interrupt dispatch code could have an event counter per
123 interrupt line, and devices could each have counters for the number
124 of interrupts that they were responsible for causing.
125 In that case, the counter for a device on a given interrupt line
126 would have the line's counter as its parent.
127 The value
128 .Dv NULL
129 is used to indicate that a counter has no parent.
130 A counter's parent must be attached before the counter is attached,
131 and detached after the counter is detached.
134 .Fn EVCNT_INITIALIZER
135 macro can be used to provide a static initializer for an event
136 counter structure.
137 It is invoked as
138 .Fn EVCNT_INITIALIZER "type" "parent" "group" "name" ,
139 and its arguments will be placed into the corresponding fields of
140 the event counter structure it is initializing.
142 .Fa group
144 .Fa name
145 arguments must be constant strings.
147 The following is a brief description of each function in the framework:
148 .Bl -tag -width indent
149 .It Fn "void evcnt_attach_dynamic" "struct evcnt *ev" "int type" "const struct evcnt *parent" "const char *group" "const char *name"
151 Attach the event counter structure pointed to by
152 .Fa ev
153 to the system event list.
154 The event counter is cleared and its fields initialized using the
155 arguments to the function call.
156 The contents of the remaining elements in the structure (e.g., the
157 name lengths) are calculated, and the counter is added to the
158 system event list.
160 The strings specified as the group and
161 counter names must persist (with the same value)
162 throughout the life of the event counter; they are referenced by,
163 not copied into, the counter.
164 .It Fn "void evcnt_attach_static" "struct evcnt *ev"
166 Attach the statically-initialized event counter structure
167 pointed to by
168 .Fa ev
169 to the system event list.
170 The event counter is assumed to be statically initialized using the
171 .Fn EVCNT_INITIALIZER
172 macro.
173 This function simply calculates structure elements' values as appropriate
174 (e.g., the string lengths), and adds the counter to the system event list.
175 .It Fn "void evcnt_detach" "struct evcnt *ev"
177 Detach the event counter structure pointed to by
178 .Fa ev
179 from the system event list.
182 Note that no method is provided to increment the value of an
183 event counter.
184 Code incrementing an event counter should do so by directly accessing its
185 .Fa ev_count
186 field in a manner that is known to be safe.
187 For instance, additions to a device's event counters in the interrupt
188 handler for that device will often be safe without additional protection
189 (because interrupt handler entries for a given device have to be
190 serialized).
191 However, for other uses of event counters, additional locking
192 or use of machine-dependent atomic operation may be appropriate.
193 (The overhead of using a mechanism that is guaranteed to
194 be safe to increment every counter, regardless of actual need
195 for such a mechanism where the counter is being incremented,
196 would be too great.
197 On some systems, it might involve a global lock and several function calls.)
198 .Sh USING THE FRAMEWORK
199 This section includes a description on basic use of the framework
200 and example usage of its functions.
202 Device drivers can use the
203 .Fn evcnt_attach_dynamic
205 .Fn evcnt_detach
206 functions to manage device-specific event counters.
207 Statically configured system modules can use
208 .Fn evcnt_attach_static
209 to configure global event counters.
210 Similarly, loadable modules can use
211 .Fn evcnt_attach_static
212 to configure their global event counters,
213 .Fn evcnt_attach_dynamic
214 to attach device-specific event
215 counters, and
216 .Fn evcnt_detach
217 to detach all counters when being unloaded.
219 Device drivers that wish to use the generic event counter
220 framework should place event counter structures in their
221 .Dq softc
222 structures.
223 For example, to keep track of the number of interrupts for a given
224 device (broken down further into
225 .Dq device readable
227 .Dq device writable
228 interrupts) a device driver might use:
229 .Bd -literal
230 struct foo_softc {
231         struct device sc_dev;           /* generic device information */
232         [ . . . ]
233         struct evcnt sc_ev_intr;        /* interrupt count */
234         struct evcnt sc_ev_intr_rd;     /* 'readable' interrupt count */
235         struct evcnt sc_ev_intr_wr;     /* 'writable' interrupt count */
236         [ . . . ]
240 In the device attach function, those counters would be registered with
241 the system using the
242 .Fn evcnt_attach_dynamic
243 function, using code like:
244 .Bd -literal
245 void
246 fooattach(parent, self, aux)
247         struct device *parent, *self;
248         void *aux;
250         struct foo_softc *sc = (struct foo_softc *)self;
252         [ . . . ]
254         /* Initialize and attach event counters. */
255         evcnt_attach_dynamic(\*[Am]sc-\*[Gt]sc_ev, EVCNT_TYPE_INTR,
256             NULL, sc-\*[Gt]sc_dev.dv_xname, "intr");
257         evcnt_attach_dynamic(\*[Am]sc-\*[Gt]sc_ev_rd, EVCNT_TYPE_INTR,
258             \*[Am]sc-\*[Gt]sc_ev, sc-\*[Gt]sc_dev.dv_xname, "intr rd");
259         evcnt_attach_dynamic(\*[Am]sc-\*[Gt]sc_ev_wr, EVCNT_TYPE_INTR,
260             \*[Am]sc-\*[Gt]sc_ev, sc-\*[Gt]sc_dev.dv_xname, "intr wr");
262         [ . . . ]
266 If the device can be detached from the system, its detach
267 function should invoke
268 .Fn evcnt_detach
269 on each attached counter (making sure to detach any
270 .Dq parent
271 counters only after detaching all children).
273 Code like the following might be used to initialize a static
274 event counter (in this example, one used to track CPU alignment traps):
275 .Bd -literal
276         struct evcnt aligntrap_ev = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
277             NULL, "cpu", "aligntrap")
280 To attach this event counter, code like the following could be used:
281 .Bd -literal
282         evcnt_attach_static(\*[Am]aligntrap_ev);
284 .Sh CODE REFERENCES
285 This section describes places within the
287 source tree where actual
288 code implementing or using the event counter framework can be found.
289 All pathnames are relative to
290 .Pa /usr/src .
292 The event counter framework itself is implemented within the file
293 .Pa sys/kern/subr_evcnt.c .
294 Data structures and function prototypes for the framework are located in
295 .Pa sys/sys/device.h .
297 Event counters are used throughout the system.
300 .Xr vmstat 1
301 source file
302 .Pa usr.bin/vmstat/vmstat.c
303 shows an example of how to access event counters from user programs.
304 .Sh SEE ALSO
305 .Xr vmstat 1
306 .Sh HISTORY
307 A set of interrupt counter interfaces with similar names to the interfaces
308 in the
310 generic event counter framework appeared as part
311 of the new autoconfiguration system in
312 .Bx 4.4 .
313 Those interfaces were never widely adopted in
315 because of limitations in their applicability.
316 (Their use was limited to non-hierarchical, dynamically
317 attached device interrupt counters.)
320 generic event counter framework first appeared in
321 .Nx 1.5 .
322 .Sh AUTHORS
325 generic event counter framework was designed and implemented by
326 .An Chris Demetriou
327 .Aq cgd@NetBSD.org .