4e76af6a41
Introduce counter(9) API, that implements fast and raceless counters, provided (but not limited to) for gathering of statistical data. See http://lists.freebsd.org/pipermail/freebsd-arch/2013-April/014204.html for more details. In collaboration with: kib Reviewed by: luigi Tested by: ae, ray Sponsored by: Nginx, Inc.
201 lines
5.4 KiB
Groff
201 lines
5.4 KiB
Groff
.\"-
|
|
.\" Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org>
|
|
.\" 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.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd April 3, 2013
|
|
.Dt COUNTER 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm counter
|
|
.Nd "SMP-friendly kernel counter implementation"
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In sys/counter.h
|
|
.Ft counter_u64_t
|
|
.Fn counter_u64_alloc "int wait"
|
|
.Ft void
|
|
.Fn counter_u64_free "counter_u64_t c"
|
|
.Ft void
|
|
.Fn counter_u64_add "counter_u64_t c" "int64_t v"
|
|
.Ft void
|
|
.Fn counter_enter
|
|
.Ft void
|
|
.Fn counter_exit
|
|
.Ft void
|
|
.Fn counter_u64_add_protected "counter_u64_t c" "int64_t v"
|
|
.Ft uint64_t
|
|
.Fn counter_u64_fetch "counter_u64_t c"
|
|
.Ft void
|
|
.Fn counter_u64_zero "counter_u64_t c"
|
|
.In sys/sysctl.h
|
|
.Fn SYSCTL_COUNTER_U64 parent nbr name access ptr val descr
|
|
.Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
|
|
.Sh DESCRIPTION
|
|
.Nm
|
|
is a generic facility to create counters
|
|
that can be utilized for any purpose (such as collecting statistical
|
|
data).
|
|
A
|
|
.Nm
|
|
is guaranteed to be lossless when several kernel threads do simultaneous
|
|
updates.
|
|
However,
|
|
.Nm
|
|
does not block the calling thread,
|
|
also no
|
|
.Xr atomic 9
|
|
operations are used for the update, therefore the counters
|
|
can be used in any non-interrupt context.
|
|
Moreover,
|
|
.Nm
|
|
has special optimisations for SMP environments, making
|
|
.Nm
|
|
update faster than simple arithmetic on the global variable.
|
|
Thus
|
|
.Nm
|
|
is considered suitable for accounting in the performance-critical
|
|
code pathes.
|
|
.Bl -tag -width indent
|
|
.It Fn counter_u64_alloc how
|
|
Allocate a new 64-bit unsigned counter.
|
|
The
|
|
.Fa wait
|
|
argument is the
|
|
.Xr malloc 9
|
|
wait flag, should be either
|
|
.Va M_NOWAIT
|
|
or
|
|
.Va M_WAITOK .
|
|
If
|
|
.Va M_WAITOK
|
|
is specified the operation may fail.
|
|
.It Fn counter_u64_free c
|
|
Free the previously allocated counter
|
|
.Fa c .
|
|
.It Fn counter_u64_add c v
|
|
Add
|
|
.Fa v
|
|
to
|
|
.Fa c .
|
|
The KPI does not guarantee any protection from wraparound.
|
|
.It Fn counter_enter
|
|
Enter mode that would allow to safely update several counters via
|
|
.Fn counter_u64_add_protected .
|
|
On some machines this expands to
|
|
.Xr critical 9
|
|
section, while on other is a nop.
|
|
See
|
|
.Sx IMPLEMENTATION DETAILS .
|
|
.It Fn counter_exit
|
|
Exit mode for updating several counters.
|
|
.It Fn counter_u64_add_protected c v
|
|
Same as
|
|
.Fn counter_u64_add ,
|
|
but should be preceded by
|
|
.Fn counter_enter .
|
|
.It Fn counter_u64_fetch c
|
|
Take a snapshot of counter
|
|
.Fa c .
|
|
The data obtained is not guaranteed to reflect the real cumulative
|
|
value for any moment.
|
|
.It Fn counter_u64_zero c
|
|
Clear the counter
|
|
.Fa c
|
|
and set it to zero.
|
|
.It Fn SYSCTL_COUNTER_U64 parent nbr name access ptr val descr
|
|
Declare a static
|
|
.Xr sysctl
|
|
oid that would represent a
|
|
.Nm .
|
|
The
|
|
.Fa ptr
|
|
argument should be a pointer to allocated
|
|
.Vt counter_u64_t .
|
|
A read of the oid returns value obtained through
|
|
.Fn counter_u64_fetch .
|
|
Any write to the oid zeroes it.
|
|
.It Fn SYSCTL_ADD_COUNTER_U64 ctx parent nbr name access ptr descr
|
|
Create a
|
|
.Xr sysctl
|
|
oid that would represent a
|
|
.Nm .
|
|
The
|
|
.Fa ptr
|
|
argument should be a pointer to allocated
|
|
.Vt counter_u64_t .
|
|
A read of the oid returns value obtained through
|
|
.Fn counter_u64_fetch .
|
|
Any write to the oid zeroes it.
|
|
.El
|
|
.Sh IMPLEMENTATION DETAILS
|
|
On all architectures
|
|
.Nm
|
|
is implemented using per-CPU data fields that are specially aligned
|
|
in memory, to avoid inter-CPU bus traffic due to shared use
|
|
of the variables between CPUs.
|
|
These are allocated using
|
|
.Va UMA_ZONE_PCPU
|
|
.Xr uma 9
|
|
zone.
|
|
The update operation only touches the field that is private to current CPU.
|
|
Fetch operation loops through all per-CPU fields and obtains a snapshot
|
|
sum of all fields.
|
|
.Pp
|
|
On amd64 a
|
|
.Nm counter
|
|
update is implemented as a single instruction without lock semantics,
|
|
operating on the private data for the current CPU,
|
|
which is safe against preemption and interrupts.
|
|
.Pp
|
|
On i386 architecture, when machine supports the cmpxchg8 instruction,
|
|
this instruction is used.
|
|
The multi-instruction sequence provides the same guarantees as the
|
|
amd64 single-instruction implementation.
|
|
.Pp
|
|
On some architectures updating a counter require a
|
|
.Xr critical 9
|
|
section.
|
|
.Sh SEE ALSO
|
|
.Xr atomic 9 ,
|
|
.Xr critical 9 ,
|
|
.Xr locking 9 ,
|
|
.Xr malloc 9 ,
|
|
.Xr sysctl 9 ,
|
|
.Xr uma 9
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
facility first appeared in
|
|
.Fx 10.0 .
|
|
.Sh AUTHORS
|
|
.An -nosplit
|
|
The
|
|
.Nm
|
|
facility was written by
|
|
.An Gleb Smirnoff
|
|
and
|
|
.An Konstantin Belousov .
|