xref: /freebsd/share/man/man9/counter.9 (revision b740c88bfb6453416926271c089262e7164dace3)
1.\"-
2.\" Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org>
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\"
14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24.\" SUCH DAMAGE.
25.\"
26.\" $FreeBSD$
27.\"
28.Dd February 7, 2014
29.Dt COUNTER 9
30.Os
31.Sh NAME
32.Nm counter
33.Nd "SMP-friendly kernel counter implementation"
34.Sh SYNOPSIS
35.In sys/types.h
36.In sys/systm.h
37.In sys/counter.h
38.Ft counter_u64_t
39.Fn counter_u64_alloc "int wait"
40.Ft void
41.Fn counter_u64_free "counter_u64_t c"
42.Ft void
43.Fn counter_u64_add "counter_u64_t c" "int64_t v"
44.Ft void
45.Fn counter_enter
46.Ft void
47.Fn counter_exit
48.Ft void
49.Fn counter_u64_add_protected "counter_u64_t c" "int64_t v"
50.Ft uint64_t
51.Fn counter_u64_fetch "counter_u64_t c"
52.Ft void
53.Fn counter_u64_zero "counter_u64_t c"
54.In sys/sysctl.h
55.Fn SYSCTL_COUNTER_U64 parent nbr name access ptr descr
56.Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
57.Sh DESCRIPTION
58.Nm
59is a generic facility to create counters
60that can be utilized for any purpose (such as collecting statistical
61data).
62A
63.Nm
64is guaranteed to be lossless when several kernel threads do simultaneous
65updates.
66However,
67.Nm
68does not block the calling thread,
69also no
70.Xr atomic 9
71operations are used for the update, therefore the counters
72can be used in any non-interrupt context.
73Moreover,
74.Nm
75has special optimisations for SMP environments, making
76.Nm
77update faster than simple arithmetic on the global variable.
78Thus
79.Nm
80is considered suitable for accounting in the performance-critical
81code pathes.
82.Bl -tag -width indent
83.It Fn counter_u64_alloc wait
84Allocate a new 64-bit unsigned counter.
85The
86.Fa wait
87argument is the
88.Xr malloc 9
89wait flag, should be either
90.Va M_NOWAIT
91or
92.Va M_WAITOK .
93If
94.Va M_NOWAIT
95is specified the operation may fail.
96.It Fn counter_u64_free c
97Free the previously allocated counter
98.Fa c .
99.It Fn counter_u64_add c v
100Add
101.Fa v
102to
103.Fa c .
104The KPI does not guarantee any protection from wraparound.
105.It Fn counter_enter
106Enter mode that would allow to safely update several counters via
107.Fn counter_u64_add_protected .
108On some machines this expands to
109.Xr critical 9
110section, while on other is a nop.
111See
112.Sx IMPLEMENTATION DETAILS .
113.It Fn counter_exit
114Exit mode for updating several counters.
115.It Fn counter_u64_add_protected c v
116Same as
117.Fn counter_u64_add ,
118but should be preceded by
119.Fn counter_enter .
120.It Fn counter_u64_fetch c
121Take a snapshot of counter
122.Fa c .
123The data obtained is not guaranteed to reflect the real cumulative
124value for any moment.
125.It Fn counter_u64_zero c
126Clear the counter
127.Fa c
128and set it to zero.
129.It Fn SYSCTL_COUNTER_U64 parent nbr name access ptr descr
130Declare a static
131.Xr sysctl
132oid that would represent a
133.Nm .
134The
135.Fa ptr
136argument should be a pointer to allocated
137.Vt counter_u64_t .
138A read of the oid returns value obtained through
139.Fn counter_u64_fetch .
140Any write to the oid zeroes it.
141.It Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
142Create a
143.Xr sysctl
144oid that would represent a
145.Nm .
146The
147.Fa ptr
148argument should be a pointer to allocated
149.Vt counter_u64_t .
150A read of the oid returns value obtained through
151.Fn counter_u64_fetch .
152Any write to the oid zeroes it.
153.El
154.Sh IMPLEMENTATION DETAILS
155On all architectures
156.Nm
157is implemented using per-CPU data fields that are specially aligned
158in memory, to avoid inter-CPU bus traffic due to shared use
159of the variables between CPUs.
160These are allocated using
161.Va UMA_ZONE_PCPU
162.Xr uma 9
163zone.
164The update operation only touches the field that is private to current CPU.
165Fetch operation loops through all per-CPU fields and obtains a snapshot
166sum of all fields.
167.Pp
168On amd64 a
169.Nm counter
170update is implemented as a single instruction without lock semantics,
171operating on the private data for the current CPU,
172which is safe against preemption and interrupts.
173.Pp
174On i386 architecture, when machine supports the cmpxchg8 instruction,
175this instruction is used.
176The multi-instruction sequence provides the same guarantees as the
177amd64 single-instruction implementation.
178.Pp
179On some architectures updating a counter require a
180.Xr critical 9
181section.
182.Sh SEE ALSO
183.Xr atomic 9 ,
184.Xr critical 9 ,
185.Xr locking 9 ,
186.Xr malloc 9 ,
187.Xr sysctl 9 ,
188.Xr uma 9
189.Sh HISTORY
190The
191.Nm
192facility first appeared in
193.Fx 10.0 .
194.Sh AUTHORS
195.An -nosplit
196The
197.Nm
198facility was written by
199.An Gleb Smirnoff
200and
201.An Konstantin Belousov .
202