summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/evcnt.9
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/evcnt.9')
-rw-r--r--static/netbsd/man9/evcnt.9315
1 files changed, 315 insertions, 0 deletions
diff --git a/static/netbsd/man9/evcnt.9 b/static/netbsd/man9/evcnt.9
new file mode 100644
index 00000000..a9c2d0e1
--- /dev/null
+++ b/static/netbsd/man9/evcnt.9
@@ -0,0 +1,315 @@
+.\" $NetBSD: evcnt.9,v 1.23 2024/09/07 19:13:29 rillig Exp $
+.\"
+.\" Copyright (c) 2000 Christopher G. Demetriou
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed for the
+.\" NetBSD Project. See https://www.NetBSD.org/ for
+.\" information about NetBSD.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
+.\"
+.Dd January 14, 2011
+.Dt EVCNT 9
+.Os
+.Sh NAME
+.Nm evcnt ,
+.Nm evcnt_attach_dynamic ,
+.Nm evcnt_attach_static ,
+.Nm evcnt_detach
+.Nd generic event counter framework
+.Sh SYNOPSIS
+.In sys/evcnt.h
+.Ft void
+.Fn evcnt_attach_dynamic "struct evcnt *ev" \
+"int type" "const struct evcnt *parent" "const char *group" "const char *name"
+.Ft void
+.Fn evcnt_attach_static "struct evcnt *ev"
+.Ft void
+.Fn evcnt_detach "struct evcnt *ev"
+.Sh DESCRIPTION
+The
+.Nx
+generic event counter framework is designed to provide a flexible and
+hierarchical event counting facility, which is useful for tracking
+system events (including device interrupts).
+.Pp
+The fundamental component of this framework is the
+.Em evcnt
+structure.
+Its user-accessible fields are:
+.Bd -literal
+struct evcnt {
+ uint64_t ev_count; /* how many have occurred */
+ TAILQ_ENTRY(evcnt) ev_list; /* entry on list of all counters */
+ unsigned char ev_type; /* counter type; see below */
+ unsigned char ev_grouplen; /* 'group' len, excluding NUL */
+ unsigned char ev_namelen; /* 'name' len, excluding NUL */
+ const struct evcnt *ev_parent; /* parent, for hierarchical ctrs */
+ const char *ev_group; /* name of group */
+ const char *ev_name; /* name of specific event */
+};
+.Ed
+.Pp
+The system maintains a global linked list of all active event counters.
+This list, called
+.Nm allevents ,
+may grow or shrink over time as event counters are dynamically
+added to and removed from the system.
+.Pp
+Each event counter is marked (in the
+.Fa ev_type
+field) with the type of event being counted.
+The following types are currently defined:
+.Bl -tag -offset indent -width EVCNT_TYPE_MISC
+.It Ev EVCNT_TYPE_MISC
+Miscellaneous; doesn't fit into one of the other types.
+.It Ev EVCNT_TYPE_INTR
+Interrupt counter, reported by
+.Ic vmstat -i .
+.It Ev EVCNT_TYPE_TRAP
+Processor trap style events.
+.El
+.Pp
+Each event counter also has a group name
+.Pq Fa ev_group
+and
+an event name
+.Pq Fa ev_name
+which are used to identify the counter.
+The group name may be shared by a set of counters.
+For example, device interrupt counters would use the name of the
+device whose interrupts are being counted as the group name.
+The counter
+name is meant to distinguish the counter from others in its group
+(and need not be unique across groups).
+Both names should be understandable by users, since they are printed
+by commands like
+.Xr vmstat 1 .
+The constant
+.Dv EVCNT_STRING_MAX
+is defined to be the maximum group or event name length in
+bytes (including the trailing
+.Dv NUL ) .
+In the current implementation it is 256.
+.Pp
+To support hierarchical tracking of events, each event counter can
+name a
+.Dq parent
+event counter.
+For instance, interrupt dispatch code could have an event counter per
+interrupt line, and devices could each have counters for the number
+of interrupts that they were responsible for causing.
+In that case, the counter for a device on a given interrupt line
+would have the line's counter as its parent.
+The value
+.Dv NULL
+is used to indicate that a counter has no parent.
+A counter's parent must be attached before the counter is attached,
+and detached after the counter is detached.
+.Pp
+The
+.Fn EVCNT_INITIALIZER
+macro can be used to provide a static initializer for an event
+counter structure.
+It is invoked as
+.Fn EVCNT_INITIALIZER "type" "parent" "group" "name" ,
+and its arguments will be placed into the corresponding fields of
+the event counter structure it is initializing.
+The
+.Fa group
+and
+.Fa name
+arguments must be constant strings.
+.Sh FUNCTIONS
+The following is a brief description of each function in the framework:
+.Bl -tag -width indent
+.It Fn evcnt_attach_dynamic "ev" "type" "parent" "group" "name"
+Attach the event counter structure pointed to by
+.Fa ev
+to the system event list.
+The event counter is cleared and its fields initialized using the
+arguments to the function call.
+The contents of the remaining elements in the structure (e.g., the
+name lengths) are calculated, and the counter is added to the
+system event list.
+.Pp
+The strings specified as the group and
+counter names must persist (with the same value)
+throughout the life of the event counter; they are referenced by,
+not copied into, the counter.
+.It Fn evcnt_attach_static "ev"
+Attach the statically-initialized event counter structure
+pointed to by
+.Fa ev
+to the system event list.
+The event counter is assumed to be statically initialized using the
+.Fn EVCNT_INITIALIZER
+macro.
+This function simply calculates structure elements' values as appropriate
+(e.g., the string lengths), and adds the counter to the system event list.
+.It Fn evcnt_detach "ev"
+Detach the event counter structure pointed to by
+.Fa ev
+from the system event list.
+.El
+.Pp
+Note that no method is provided to increment the value of an
+event counter.
+Code incrementing an event counter should do so by directly accessing its
+.Fa ev_count
+field in a manner that is known to be safe.
+For instance, additions to a device's event counters in the interrupt
+handler for that device will often be safe without additional protection
+(because interrupt handler entries for a given device have to be
+serialized).
+However, for other uses of event counters, additional locking
+or use of machine-dependent atomic operation may be appropriate.
+(The overhead of using a mechanism that is guaranteed to
+be safe to increment every counter, regardless of actual need
+for such a mechanism where the counter is being incremented,
+would be too great.
+On some systems, it might involve a global lock and several function calls.)
+.Sh EXAMPLES
+This section includes a description on basic use of the framework
+and example usage of its functions.
+.Pp
+Device drivers can use the
+.Fn evcnt_attach_dynamic
+and
+.Fn evcnt_detach
+functions to manage device-specific event counters.
+Statically configured system modules can use
+.Fn evcnt_attach_static
+to configure global event counters.
+Similarly, loadable modules can use
+.Fn evcnt_attach_static
+to configure their global event counters,
+.Fn evcnt_attach_dynamic
+to attach device-specific event
+counters, and
+.Fn evcnt_detach
+to detach all counters when being unloaded.
+.Pp
+Device drivers that wish to use the generic event counter
+framework should place event counter structures in their
+.Dq softc
+structures.
+For example, to keep track of the number of interrupts for a given
+device (broken down further into
+.Dq device readable
+and
+.Dq device writable
+interrupts) a device driver might use:
+.Bd -literal
+struct foo_softc {
+ [ . . . ]
+ struct evcnt sc_ev_intr; /* interrupt count */
+ struct evcnt sc_ev_intr_rd; /* 'readable' interrupt count */
+ struct evcnt sc_ev_intr_wr; /* 'writable' interrupt count */
+ [ . . . ]
+};
+.Ed
+.Pp
+In the device attach function, those counters would be registered with
+the system using the
+.Fn evcnt_attach_dynamic
+function, using code like:
+.Bd -literal
+void
+fooattach(device_t parent, device_t self, void *aux)
+{
+ struct foo_softc *sc = device_private(self);
+
+ [ . . . ]
+
+ /* Initialize and attach event counters. */
+ evcnt_attach_dynamic(&sc->sc_ev, EVCNT_TYPE_INTR,
+ NULL, device_xname(self), "intr");
+ evcnt_attach_dynamic(&sc->sc_ev_rd, EVCNT_TYPE_INTR,
+ &sc->sc_ev, device_xname(self), "intr rd");
+ evcnt_attach_dynamic(&sc->sc_ev_wr, EVCNT_TYPE_INTR,
+ &sc->sc_ev, device_xname(self), "intr wr");
+
+ [ . . . ]
+}
+.Ed
+.Pp
+If the device can be detached from the system, its detach
+function should invoke
+.Fn evcnt_detach
+on each attached counter (making sure to detach any
+.Dq parent
+counters only after detaching all children).
+.Pp
+Code like the following might be used to initialize a static
+event counter (in this example, one used to track CPU alignment traps):
+.Bd -literal
+ struct evcnt aligntrap_ev = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
+ NULL, "cpu", "aligntrap")
+.Ed
+.Pp
+To attach this event counter, code like the following could be used:
+.Bd -literal
+ evcnt_attach_static(&aligntrap_ev);
+.Ed
+.Sh CODE REFERENCES
+The event counter framework itself is implemented within the file
+.Pa sys/kern/subr_evcnt.c .
+Data structures and function prototypes for the framework are located in
+.Pa sys/sys/device.h .
+.Pp
+Event counters are used throughout the system.
+.Pp
+The
+.Xr vmstat 1
+source file
+.Pa usr.bin/vmstat/vmstat.c
+shows an example of how to access event counters from user programs.
+.Sh SEE ALSO
+.Xr vmstat 1
+.Sh HISTORY
+A set of interrupt counter interfaces with similar names to the interfaces
+in the
+.Nx
+generic event counter framework appeared as part
+of the new autoconfiguration system in
+.Bx 4.4 .
+Those interfaces were never widely adopted in
+.Nx
+because of limitations in their applicability.
+(Their use was limited to non-hierarchical, dynamically
+attached device interrupt counters.)
+The
+.Nx
+generic event counter framework first appeared in
+.Nx 1.5 .
+.Sh AUTHORS
+The
+.Nx
+generic event counter framework was designed and implemented by
+.An Chris Demetriou
+.Aq cgd@NetBSD.org .