xref: /freebsd/share/man/man9/counter.9 (revision fa9896e082a1046ff4fbc75fcba4d18d1f2efc19)
14e76af6aSGleb Smirnoff.\"-
24e76af6aSGleb Smirnoff.\" Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org>
34e76af6aSGleb Smirnoff.\" All rights reserved.
44e76af6aSGleb Smirnoff.\"
54e76af6aSGleb Smirnoff.\" Redistribution and use in source and binary forms, with or without
64e76af6aSGleb Smirnoff.\" modification, are permitted provided that the following conditions
74e76af6aSGleb Smirnoff.\" are met:
84e76af6aSGleb Smirnoff.\" 1. Redistributions of source code must retain the above copyright
94e76af6aSGleb Smirnoff.\"    notice, this list of conditions and the following disclaimer.
104e76af6aSGleb Smirnoff.\" 2. Redistributions in binary form must reproduce the above copyright
114e76af6aSGleb Smirnoff.\"    notice, this list of conditions and the following disclaimer in the
124e76af6aSGleb Smirnoff.\"    documentation and/or other materials provided with the distribution.
134e76af6aSGleb Smirnoff.\"
144e76af6aSGleb Smirnoff.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
154e76af6aSGleb Smirnoff.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164e76af6aSGleb Smirnoff.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
174e76af6aSGleb Smirnoff.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
184e76af6aSGleb Smirnoff.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
194e76af6aSGleb Smirnoff.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
204e76af6aSGleb Smirnoff.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
214e76af6aSGleb Smirnoff.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
224e76af6aSGleb Smirnoff.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234e76af6aSGleb Smirnoff.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
244e76af6aSGleb Smirnoff.\" SUCH DAMAGE.
254e76af6aSGleb Smirnoff.\"
26*51dc8e7fSKristof Provost.Dd March 11, 2021
274e76af6aSGleb Smirnoff.Dt COUNTER 9
284e76af6aSGleb Smirnoff.Os
294e76af6aSGleb Smirnoff.Sh NAME
304e76af6aSGleb Smirnoff.Nm counter
314e76af6aSGleb Smirnoff.Nd "SMP-friendly kernel counter implementation"
324e76af6aSGleb Smirnoff.Sh SYNOPSIS
334e76af6aSGleb Smirnoff.In sys/types.h
342d875db3SGleb Smirnoff.In sys/systm.h
354e76af6aSGleb Smirnoff.In sys/counter.h
364e76af6aSGleb Smirnoff.Ft counter_u64_t
374e76af6aSGleb Smirnoff.Fn counter_u64_alloc "int wait"
384e76af6aSGleb Smirnoff.Ft void
394e76af6aSGleb Smirnoff.Fn counter_u64_free "counter_u64_t c"
404e76af6aSGleb Smirnoff.Ft void
414e76af6aSGleb Smirnoff.Fn counter_u64_add "counter_u64_t c" "int64_t v"
424e76af6aSGleb Smirnoff.Ft void
434e76af6aSGleb Smirnoff.Fn counter_enter
444e76af6aSGleb Smirnoff.Ft void
454e76af6aSGleb Smirnoff.Fn counter_exit
464e76af6aSGleb Smirnoff.Ft void
474e76af6aSGleb Smirnoff.Fn counter_u64_add_protected "counter_u64_t c" "int64_t v"
484e76af6aSGleb Smirnoff.Ft uint64_t
494e76af6aSGleb Smirnoff.Fn counter_u64_fetch "counter_u64_t c"
504e76af6aSGleb Smirnoff.Ft void
514e76af6aSGleb Smirnoff.Fn counter_u64_zero "counter_u64_t c"
5216917020SGleb Smirnoff.Ft int64_t
5316917020SGleb Smirnoff.Fn counter_ratecheck "struct counter_rate *cr" "int64_t limit"
54fffcb56fSMark Johnston.Fn COUNTER_U64_SYSINIT "counter_u64_t c"
55fffcb56fSMark Johnston.Fn COUNTER_U64_DEFINE_EARLY "counter_u64_t c"
564e76af6aSGleb Smirnoff.In sys/sysctl.h
57369f5bceSGleb Smirnoff.Fn SYSCTL_COUNTER_U64 parent nbr name access ptr descr
584e76af6aSGleb Smirnoff.Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
59b5b7b142SGleb Smirnoff.Fn SYSCTL_COUNTER_U64_ARRAY parent nbr name access ptr len descr
60b5b7b142SGleb Smirnoff.Fn SYSCTL_ADD_COUNTER_U64_ARRAY ctx parent nbr name access ptr len descr
614e76af6aSGleb Smirnoff.Sh DESCRIPTION
624e76af6aSGleb Smirnoff.Nm
634e76af6aSGleb Smirnoffis a generic facility to create counters
644e76af6aSGleb Smirnoffthat can be utilized for any purpose (such as collecting statistical
654e76af6aSGleb Smirnoffdata).
664e76af6aSGleb SmirnoffA
674e76af6aSGleb Smirnoff.Nm
684e76af6aSGleb Smirnoffis guaranteed to be lossless when several kernel threads do simultaneous
694e76af6aSGleb Smirnoffupdates.
704e76af6aSGleb SmirnoffHowever,
714e76af6aSGleb Smirnoff.Nm
724e76af6aSGleb Smirnoffdoes not block the calling thread,
734e76af6aSGleb Smirnoffalso no
744e76af6aSGleb Smirnoff.Xr atomic 9
754e76af6aSGleb Smirnoffoperations are used for the update, therefore the counters
764e76af6aSGleb Smirnoffcan be used in any non-interrupt context.
774e76af6aSGleb SmirnoffMoreover,
784e76af6aSGleb Smirnoff.Nm
794e76af6aSGleb Smirnoffhas special optimisations for SMP environments, making
804e76af6aSGleb Smirnoff.Nm
814e76af6aSGleb Smirnoffupdate faster than simple arithmetic on the global variable.
824e76af6aSGleb SmirnoffThus
834e76af6aSGleb Smirnoff.Nm
844e76af6aSGleb Smirnoffis considered suitable for accounting in the performance-critical
857c64ddd5SWarren Blockcode paths.
864e76af6aSGleb Smirnoff.Bl -tag -width indent
87fa8175e4SBrad Davis.It Fn counter_u64_alloc wait
884e76af6aSGleb SmirnoffAllocate a new 64-bit unsigned counter.
894e76af6aSGleb SmirnoffThe
904e76af6aSGleb Smirnoff.Fa wait
914e76af6aSGleb Smirnoffargument is the
924e76af6aSGleb Smirnoff.Xr malloc 9
934e76af6aSGleb Smirnoffwait flag, should be either
944e76af6aSGleb Smirnoff.Va M_NOWAIT
954e76af6aSGleb Smirnoffor
964e76af6aSGleb Smirnoff.Va M_WAITOK .
974e76af6aSGleb SmirnoffIf
98c676e669SAlan Somers.Va M_NOWAIT
99*51dc8e7fSKristof Provostis specified the operation may fail and return
100*51dc8e7fSKristof Provost.Dv NULL .
1014e76af6aSGleb Smirnoff.It Fn counter_u64_free c
1024e76af6aSGleb SmirnoffFree the previously allocated counter
1034e76af6aSGleb Smirnoff.Fa c .
104*51dc8e7fSKristof ProvostIt is safe to pass
105*51dc8e7fSKristof Provost.Dv NULL .
1064e76af6aSGleb Smirnoff.It Fn counter_u64_add c v
1074e76af6aSGleb SmirnoffAdd
1084e76af6aSGleb Smirnoff.Fa v
1094e76af6aSGleb Smirnoffto
1104e76af6aSGleb Smirnoff.Fa c .
1114e76af6aSGleb SmirnoffThe KPI does not guarantee any protection from wraparound.
1124e76af6aSGleb Smirnoff.It Fn counter_enter
113640ca09dSEnji CooperEnter mode that would allow the safe update of several counters via
1144e76af6aSGleb Smirnoff.Fn counter_u64_add_protected .
1154e76af6aSGleb SmirnoffOn some machines this expands to
1164e76af6aSGleb Smirnoff.Xr critical 9
1174e76af6aSGleb Smirnoffsection, while on other is a nop.
1184e76af6aSGleb SmirnoffSee
1194e76af6aSGleb Smirnoff.Sx IMPLEMENTATION DETAILS .
1204e76af6aSGleb Smirnoff.It Fn counter_exit
1214e76af6aSGleb SmirnoffExit mode for updating several counters.
1224e76af6aSGleb Smirnoff.It Fn counter_u64_add_protected c v
1234e76af6aSGleb SmirnoffSame as
1244e76af6aSGleb Smirnoff.Fn counter_u64_add ,
1254e76af6aSGleb Smirnoffbut should be preceded by
1264e76af6aSGleb Smirnoff.Fn counter_enter .
1274e76af6aSGleb Smirnoff.It Fn counter_u64_fetch c
1284e76af6aSGleb SmirnoffTake a snapshot of counter
1294e76af6aSGleb Smirnoff.Fa c .
1304e76af6aSGleb SmirnoffThe data obtained is not guaranteed to reflect the real cumulative
1314e76af6aSGleb Smirnoffvalue for any moment.
1324e76af6aSGleb Smirnoff.It Fn counter_u64_zero c
1334e76af6aSGleb SmirnoffClear the counter
1344e76af6aSGleb Smirnoff.Fa c
1354e76af6aSGleb Smirnoffand set it to zero.
13616917020SGleb Smirnoff.It Fn counter_ratecheck cr limit
13716917020SGleb SmirnoffThe function is a multiprocessor-friendly version of
13899d528d4SDag-Erling Smørgrav.Fn ppsratecheck
13916917020SGleb Smirnoffwhich uses
14016917020SGleb Smirnoff.Nm
14116917020SGleb Smirnoffinternally.
142640ca09dSEnji CooperReturns non-negative value if the rate is not yet reached during the current
14316917020SGleb Smirnoffsecond, and a negative value otherwise.
14416917020SGleb SmirnoffIf the limit was reached on previous second, but was just reset back to zero,
14516917020SGleb Smirnoffthen
14616917020SGleb Smirnoff.Fn counter_ratecheck
14716917020SGleb Smirnoffreturns number of events since previous reset.
148fffcb56fSMark Johnston.It Fn COUNTER_U64_SYSINIT c
149fffcb56fSMark JohnstonDefine a
150fffcb56fSMark Johnston.Xr SYSINIT 9
151fffcb56fSMark Johnstoninitializer for the global counter
152fffcb56fSMark Johnston.Fa c .
153fffcb56fSMark Johnston.It Fn COUNTER_U64_DEFINE_EARLY c
154fffcb56fSMark JohnstonDefine and initialize a global counter
155fffcb56fSMark Johnston.Fa c .
156fffcb56fSMark JohnstonIt is always safe to increment
157fffcb56fSMark Johnston.Fa c ,
158fffcb56fSMark Johnstonthough updates prior to the
159fffcb56fSMark Johnston.Dv SI_SUB_COUNTER
160fffcb56fSMark Johnston.Xr SYSINIT 9
161fffcb56fSMark Johnstonevent are lost.
162369f5bceSGleb Smirnoff.It Fn SYSCTL_COUNTER_U64 parent nbr name access ptr descr
1634e76af6aSGleb SmirnoffDeclare a static
164640ca09dSEnji Cooper.Xr sysctl 9
1654e76af6aSGleb Smirnoffoid that would represent a
1664e76af6aSGleb Smirnoff.Nm .
1674e76af6aSGleb SmirnoffThe
1684e76af6aSGleb Smirnoff.Fa ptr
1694e76af6aSGleb Smirnoffargument should be a pointer to allocated
1704e76af6aSGleb Smirnoff.Vt counter_u64_t .
1714e76af6aSGleb SmirnoffA read of the oid returns value obtained through
1724e76af6aSGleb Smirnoff.Fn counter_u64_fetch .
1734e76af6aSGleb SmirnoffAny write to the oid zeroes it.
1744e76af6aSGleb Smirnoff.It Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
1754e76af6aSGleb SmirnoffCreate a
176640ca09dSEnji Cooper.Xr sysctl 9
1774e76af6aSGleb Smirnoffoid that would represent a
1784e76af6aSGleb Smirnoff.Nm .
1794e76af6aSGleb SmirnoffThe
1804e76af6aSGleb Smirnoff.Fa ptr
1814e76af6aSGleb Smirnoffargument should be a pointer to allocated
1824e76af6aSGleb Smirnoff.Vt counter_u64_t .
1834e76af6aSGleb SmirnoffA read of the oid returns value obtained through
1844e76af6aSGleb Smirnoff.Fn counter_u64_fetch .
1854e76af6aSGleb SmirnoffAny write to the oid zeroes it.
186b5b7b142SGleb Smirnoff.It Fn SYSCTL_COUNTER_U64_ARRAY parent nbr name access ptr len descr
187b5b7b142SGleb SmirnoffDeclare a static
188640ca09dSEnji Cooper.Xr sysctl 9
189b5b7b142SGleb Smirnoffoid that would represent an array of
190b5b7b142SGleb Smirnoff.Nm .
191b5b7b142SGleb SmirnoffThe
192b5b7b142SGleb Smirnoff.Fa ptr
193b5b7b142SGleb Smirnoffargument should be a pointer to allocated array of
194b5b7b142SGleb Smirnoff.Vt counter_u64_t's .
195b5b7b142SGleb SmirnoffThe
196b5b7b142SGleb Smirnoff.Fa len
197b5b7b142SGleb Smirnoffargument should specify number of elements in the array.
198b5b7b142SGleb SmirnoffA read of the oid returns len-sized array of
199b5b7b142SGleb Smirnoff.Vt uint64_t
200b5b7b142SGleb Smirnoffvalues  obtained through
201b5b7b142SGleb Smirnoff.Fn counter_u64_fetch .
202b5b7b142SGleb SmirnoffAny write to the oid zeroes all array elements.
203b5b7b142SGleb Smirnoff.It Fn SYSCTL_ADD_COUNTER_U64_ARRAY ctx parent nbr name access ptr len descr
204b5b7b142SGleb SmirnoffCreate a
205640ca09dSEnji Cooper.Xr sysctl 9
206b5b7b142SGleb Smirnoffoid that would represent an array of
207b5b7b142SGleb Smirnoff.Nm .
208b5b7b142SGleb SmirnoffThe
209b5b7b142SGleb Smirnoff.Fa ptr
210b5b7b142SGleb Smirnoffargument should be a pointer to allocated array of
211b5b7b142SGleb Smirnoff.Vt counter_u64_t's .
212b5b7b142SGleb SmirnoffThe
213b5b7b142SGleb Smirnoff.Fa len
214b5b7b142SGleb Smirnoffargument should specify number of elements in the array.
215b5b7b142SGleb SmirnoffA read of the oid returns len-sized array of
216b5b7b142SGleb Smirnoff.Vt uint64_t
217b5b7b142SGleb Smirnoffvalues obtained through
218b5b7b142SGleb Smirnoff.Fn counter_u64_fetch .
219b5b7b142SGleb SmirnoffAny write to the oid zeroes all array elements.
2204e76af6aSGleb Smirnoff.El
2214e76af6aSGleb Smirnoff.Sh IMPLEMENTATION DETAILS
2224e76af6aSGleb SmirnoffOn all architectures
2234e76af6aSGleb Smirnoff.Nm
2244e76af6aSGleb Smirnoffis implemented using per-CPU data fields that are specially aligned
2254e76af6aSGleb Smirnoffin memory, to avoid inter-CPU bus traffic due to shared use
2264e76af6aSGleb Smirnoffof the variables between CPUs.
2274e76af6aSGleb SmirnoffThese are allocated using
2284e76af6aSGleb Smirnoff.Va UMA_ZONE_PCPU
2294e76af6aSGleb Smirnoff.Xr uma 9
2304e76af6aSGleb Smirnoffzone.
2314e76af6aSGleb SmirnoffThe update operation only touches the field that is private to current CPU.
2324e76af6aSGleb SmirnoffFetch operation loops through all per-CPU fields and obtains a snapshot
2334e76af6aSGleb Smirnoffsum of all fields.
2344e76af6aSGleb Smirnoff.Pp
2354e76af6aSGleb SmirnoffOn amd64 a
2364e76af6aSGleb Smirnoff.Nm counter
2374e76af6aSGleb Smirnoffupdate is implemented as a single instruction without lock semantics,
2384e76af6aSGleb Smirnoffoperating on the private data for the current CPU,
2394e76af6aSGleb Smirnoffwhich is safe against preemption and interrupts.
2404e76af6aSGleb Smirnoff.Pp
2414e76af6aSGleb SmirnoffOn i386 architecture, when machine supports the cmpxchg8 instruction,
2424e76af6aSGleb Smirnoffthis instruction is used.
2434e76af6aSGleb SmirnoffThe multi-instruction sequence provides the same guarantees as the
2444e76af6aSGleb Smirnoffamd64 single-instruction implementation.
2454e76af6aSGleb Smirnoff.Pp
2464e76af6aSGleb SmirnoffOn some architectures updating a counter require a
2474e76af6aSGleb Smirnoff.Xr critical 9
2484e76af6aSGleb Smirnoffsection.
249a435d46fSHans Petter Selasky.Sh EXAMPLES
250a435d46fSHans Petter SelaskyThe following example creates a static counter array exported to
251a435d46fSHans Petter Selaskyuserspace through a sysctl:
252a435d46fSHans Petter Selasky.Bd -literal -offset indent
253a435d46fSHans Petter Selasky#define MY_SIZE 8
254a435d46fSHans Petter Selaskystatic counter_u64_t array[MY_SIZE];
255a435d46fSHans Petter SelaskySYSCTL_COUNTER_U64_ARRAY(_debug, OID_AUTO, counter_array, CTLFLAG_RW,
256a435d46fSHans Petter Selasky    &array[0], MY_SIZE, "Test counter array");
257a435d46fSHans Petter Selasky.Ed
2584e76af6aSGleb Smirnoff.Sh SEE ALSO
2594e76af6aSGleb Smirnoff.Xr atomic 9 ,
2604e76af6aSGleb Smirnoff.Xr critical 9 ,
2614e76af6aSGleb Smirnoff.Xr locking 9 ,
2624e76af6aSGleb Smirnoff.Xr malloc 9 ,
26399d528d4SDag-Erling Smørgrav.Xr ratecheck 9 ,
2644e76af6aSGleb Smirnoff.Xr sysctl 9 ,
265fffcb56fSMark Johnston.Xr SYSINIT 9 ,
2664e76af6aSGleb Smirnoff.Xr uma 9
2674e76af6aSGleb Smirnoff.Sh HISTORY
2684e76af6aSGleb SmirnoffThe
2694e76af6aSGleb Smirnoff.Nm
2704e76af6aSGleb Smirnofffacility first appeared in
2714e76af6aSGleb Smirnoff.Fx 10.0 .
2724e76af6aSGleb Smirnoff.Sh AUTHORS
2734e76af6aSGleb Smirnoff.An -nosplit
2744e76af6aSGleb SmirnoffThe
2754e76af6aSGleb Smirnoff.Nm
2764e76af6aSGleb Smirnofffacility was written by
2774e76af6aSGleb Smirnoff.An Gleb Smirnoff
2784e76af6aSGleb Smirnoffand
2794e76af6aSGleb Smirnoff.An Konstantin Belousov .
280