xref: /freebsd-13.1/lib/libmemstat/libmemstat.3 (revision e754c6bb)
1.\" Copyright (c) 2005 Robert N. M. Watson
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd June 27, 2005
28.Os
29.Dt LIBMEMSTAT 3
30.Sh NAME
31.Nm libmemstat
32.Nd "library interface to retrieve kernel memory allocator statistics"
33.Sh LIBRARY
34.Lb libmemstat
35.Sh SYNOPSIS
36.In sys/types.h
37.In memstat.h
38.Ss General Functions
39.Ft const char *
40.Fn memstat_strerror "int error"
41.Ss Memory Type List Management Functions
42.Ft struct memory_type_list *
43.Fn memstat_mtl_alloc "void"
44.Ft struct memory_type *
45.Fn memstat_mtl_first "struct memory_type_list *list"
46.Ft struct memory_type *
47.Fn memstat_mtl_next "struct memory_type *mtp"
48.Ft struct memory_type *
49.Fn memstat_mtl_find "struct memory_type_list *list" "int allocator" "const char *name"
50.Ft void
51.Fn memstat_mtl_free "struct memory_type_list *list"
52.Ft int
53.Fn memstat_mtl_geterror "struct memory_type_list *list"
54.Ss Allocator Query Functions
55.Ft int
56.Fn memstat_sysctl_all "struct memory_type_list *list" "int flags"
57.Ft int
58.Fn memstat_sysctl_malloc "struct memory_type_list *list" "int flags"
59.Ft int
60.Fn memstat_sysctl_uma "struct memory_type_list *list" "int flags"
61.Ss Memory Type Accessor Methods
62.Ft const char *
63.Fn memstat_get_name "const struct memory_type *mtp"
64.Ft int
65.Fn memstat_get_allocator "const struct memory_type *mtp"
66.Ft uint64_t
67.Fn memstat_get_countlimit "const struct memory_type *mtp"
68.Ft uint64_t
69.Fn memstat_get_byteslimit "const struct memory_type *mtp"
70.Ft uint64_t
71.Fn memstat_get_sizemask "const struct memory_type *mtp"
72.Ft uint64_t
73.Fn memstat_get_size "const struct memory_type *mtp"
74.Ft uint64_t
75.Fn memstat_get_memalloced "const struct memory_type *mtp"
76.Ft uint64_t
77.Fn memstat_get_memfreed "const struct memory_type *mtp"
78.Ft uint64_t
79.Fn memstat_get_numallocs "const struct memory_type *mtp"
80.Ft uint64_t
81.Fn memstat_get_numfrees "const struct memory_type *mtp"
82.Ft uint64_t
83.Fn memstat_get_bytes "const struct memory_type *mtp"
84.Ft uint64_t
85.Fn memstat_get_count "const struct memory_type *mtp"
86.Ft uint64_t
87.Fn memstat_get_free "const struct memory_type *mtp"
88.Ft uint64_t
89.Fn memstat_get_failures "const struct memory_type *mtp"
90.Ft void *
91.Fn memstat_get_caller_pointer "const struct memory_type *mtp" "int index"
92.Ft void
93.Fn memstat_set_caller_pointer "struct memory_type *mtp" "int index" "void *value"
94.Ft uint64_t
95.Fn memstat_get_caller_uint64 "const struct memory_type *mtp" "int index"
96.Ft void
97.Fn memstat_set_caller_uint64 "struct memory_type *mtp" "int index" "uint64_t value"
98.Ft uint64_t
99.Fn memstat_get_zonefree "const struct memory_type *mtp"
100.Ft uint64_t
101.Fn memstat_get_kegfree "const struct memory_type *mtp"
102.Ft uint64_t
103.Fn memstat_get_percpu_memalloced "const struct memory_type *mtp" "int cpu"
104.Ft uint64_t
105.Fn memstat_get_percpu_memfreed "const struct memory_type *mtp" "int cpu"
106.Ft uint64_t
107.Fn memstat_get_percpu_numallocs "const struct memory_type *mtp" "int cpu"
108.Ft uint64_t
109.Fn memstat_get_percpu_numfrees "const struct memory_type *mtp" "int cpu"
110.Ft uint64_t
111.Fn memstat_get_percpu_sizemask "const struct memory_type *mtp" "int cpu"
112.Ft void *
113.Fn memstat_get_percpu_caller_pointer "const struct memory_type *mtp" "int cpu" "int index"
114.Ft void
115.Fn memstat_set_percpu_caller_pointer "struct memory_type *mtp" "int cpu" "int index" "void *value"
116.Ft uint64_t
117.Fn memstat_get_percpu_caller_uint64 "const struct memory_type *mtp" "int cpu" "int index"
118.Ft void
119.Fn memstat_set_percpu_caller_uint64 "struct memory_type *mtp" "int cpu" "int index" "uint64_t value"
120.Ft uint64_t
121.Fn memstat_get_percpu_free "const struct memory_type *mtp" "int cpu"
122.Sh DESCRIPTION
123.Nm
124provides an interface to retrieve kernel memory allocator statistics, for
125the purposes of debugging and system monitoring, insulating applications
126from implementation details of the allocators, and allowing a tool to
127transparently support multiple allocators.
128.Nm
129supports both retrieving a single statistics snapshot, as well as
130incrementally updating statistics for long-term monitoring.
131.Pp
132.Nm
133describes each memory type using a
134.Vt struct memory_type ,
135an opaque memory type accessed by the application using accessor functions
136in the library.
137.Nm
138returns and updates chains of
139.Vt struct memory_type
140via a
141.Vt struct memory_type_list ,
142which will be allocated by calling
143.Fn memstat_mtl_alloc ,
144and freed on completion using
145.Fn memstat_mtl_free .
146Lists of memory types are populated via calls that query the kernel for
147statistics information; currently:
148.Fn memstat_sysctl_all ,
149.Fn memstat_sysctl_uma ,
150and
151.Fn memstat_sysctl_malloc .
152Repeated calls will incrementally update the list of memory types, permitting
153tracking over time without recreating all list state.
154If an error is detected during a query call, error condition information may
155be retrieved using
156.Fn memstat_mtl_geterror ,
157and converted to a user-readable string using
158.Fn memstat_strerror .
159.Pp
160Freeing the list will free all memory type data in the list, and so
161invalidates any outstanding pointers to entries in the list.
162.Vt struct memory_type
163entries in the list may be iterated over using
164.Fn memstat_mtl_first
165and
166.fn memstat_mtl_next ,
167which respectively return the first entry in a list, and the next entry in a
168list.
169.Fn memstat_mtl_find ,
170which will return a pointer to the first entry matching the passed
171parameters.
172.Pp
173A series of accessor methods is provided to access fields of the structure,
174including retrieving statistics and properties, as well as setting of caller
175owned fields.
176Direct application access to the data structure fields is not supported.
177.Ss Library memory_type Fields
178Each
179.Vt struct memory_type
180holds a description of the memory type, including its name and the allocator
181it is managed by, as well as current statistics on use.
182Some statistics are directly measured, others are derived from directly
183measured statistics.
184Certain high level statistics are present across all available allocators,
185such as the number of allocation and free operations; other measurements,
186such as the quantity of free items in per-CPU caches, or administrative
187limit on the number of allocations, is available only for specific
188allocators.
189.Ss Caller memory_type Fields
190.Vt struct memory_type
191includes fields to allow the application to store data, in the form of
192pointers and 64-bit integers, with memory types.
193For example, the application author might make use of one of the caller
194pointers to reference a more complex data structure tracking long-term
195behavior of the memory type, or a window system object that is used to
196render the state of the memory type.
197General and per-CPU storage is provided with each
198.Vt struct memory_type
199in the form of an array of pointers and integers.
200The array entries are accessed via the
201.Fa index
202argument to the get and set accessor methods.
203Possible values of
204.Fa index
205range between
206.Dv 0
207and
208.Dv MEMSTAT_MAXCALLER .
209.Pp
210Caller-owned fields are initialized to
211.Dv 0
212or
213.Dv NULL
214when a new
215.Vt struct memory_type
216is allocated and attached to a memory type list; these fields retain their
217values across queries that update library-owned fields.
218.Ss Allocator Types
219Currently,
220.Nm
221supports two kernel allocators:
222.Dv ALLOCATOR_UMA
223for
224.Xr uma 9 ,
225and
226.Dv ALLOCATOR_MALLOC
227for
228.Xr malloc 9 .
229These values may be passed to
230.Fn memstat_mtl_find ,
231and will be returned by
232.Fn memstat_get_allocator .
233Two additional constants in the allocator name space are defined:
234.Dv ALLOCATOR_UNKNOWN ,
235which will only be returned as a result of a library error, and
236.Dv ALLOCATOR_ANY ,
237which can be used to specify that returning types matching any allocator is
238permittible from
239.Fn memstat_mtl_find .
240.Ss Access Method List
241The following accessor methods are defined, of which some will be valid for
242a given memory type:
243.Pp
244.Bl -tag -width "memstat_get_name" -compact -offset wee
245.It memstat_get_name
246Return a pointer to the name of the memory type.
247Memory for the name is owned by
248.Nm
249and will be valid through a call to
250.Fn memstat_mtl_free .
251Note that names will be unique with respect to a single allocator, but that
252the same name might be used by different memory types owned by different
253memory allocators.
254.It memstat_get_allocator
255Return an integer identifier for the memory allocator that owns the memory
256type.
257.It memstat_get_countlimit
258If the memory type has an administrative limit on the number of simultaneous
259allocations, return it.
260.It memstat_get_byteslimit
261If the memory type has an administrative limit on the number of bytes of
262memory that may be simultaenously allocated for the memory type, return it.
263.It memstat_get_sizemask
264If the memory type supports variable allocation sizes, return a bitmask of
265sizes allocated for the memory type.
266.It memstat_get_size
267If the memory type supports a fixed allocation size, return that size.
268.It memstat_get_memalloced
269Return the total number of bytes allocated for the memory type over its
270lifetime.
271.It memstat_get_memfreed
272Return the total number of bytes freed for the memory type over its lifetime.
273.It memstat_get_numallocs
274Return the total number of allocations for the memory type over its lifetime.
275.It memstat_get_numfrees
276Return the total number of frees for the memory type over its lifetime.
277.It memstat_get_bytes
278Return the current number of bytes allocated to the memory type.
279.It memstat_get_count
280Return the current number of allocations for the memory type.
281.It memstat_get_free
282If the memory allocator supports a cache, return the number of items in the
283cache.
284.It memstat_get_failures
285If the memory allocator and type permit allocation failures, return the
286number of allocation failures measured.
287.It memstat_get_caller_pointer
288Return a caller-owned pointer for the memory type.
289.It memstat_set_caller_pointer
290Set a caller-owned pointer for the memory type.
291.It memstat_get_caller_uint64
292Return a caller-owned integer for the memory type.
293.It memstat_set_caller_uint64
294Set a caller-owned integer for the memory type.
295.It memstat_get_zonefree
296If the memory allocator supports a multi-level allocation structure, return
297the number of cached items in the zone.
298These items will be in a fully constructed state available for immediate
299use.
300.It memstat_get_kegfree
301If the memory allocator supports a multi-level allocation structure, return
302the number of cached items in the keg.
303These items may be in a partially constructed state, and may require further
304processing before they can be made available for use.
305.It memstat_get_percpu_memalloced
306If the memory allocator supports per-CPU statistics, return the number of
307bytes of memory allocated for the memory type on the CPU over its lifetime.
308.It memstat_get_percpu_memfreed
309If the memory allocator supports per-CPU statistics, return the number of
310bytes of memory freed from the memory type on the CPU over its lifetime.
311.It memstat_get_percpu_numallocs
312If the memory allocator supports per-CPU statistics, return the number of
313allocations for the memory type on the CPU over its lifetime.
314.It memstat_get_percpu_numfrees
315If the memory allocator supports per-CPU statistics, return the number of
316frees for the memory type on the CPU over its lifetime.
317.It memstat_get_percpu_sizemask
318If the memory allocator supports variable size memory allocation and per-CPU
319statistics, return the size bitmask for the memory type on the CPU.
320.It memstat_get_percpu_caller_pointer
321Return a caller-owned per-CPU pointer for the memory type.
322.It memstat_set_percpu_caller_pointer
323Set a caller-owned per-CPU pointer for the memory type.
324.It memstat_get_percpu_caller_uint64
325Return a caller-owned per-CPU integer for the memory type.
326.It memsttat_set_percpu_caller_uint64
327Set a caller-owned per-CPU integer for the memory type.
328.It memstat_get_percpu_free
329If the memory allocator supports a per-CPU cache, return the number of free
330items in the per-CPU cache of the designated CPU.
331.El
332.Sh RETURN VALUES
333.Nm
334functions fall into three categories: functions returning a pointer to an
335object, functions returning an integer return value, and functions
336implementing accessor methods returning data from a
337.Vt struct memory_type .
338.Pp
339Functions returning a pointer to an object will generally return
340.Dv NULL
341on failure.
342.Fn memstat_mtl_alloc
343will return an error value via
344.Va errno ,
345which will consist of the value
346.Dv ENOMEM .
347Functions
348.Fn memstat_mtl_first ,
349.Fn memstat_mtl_next ,
350and
351.Fn memstat_mtl_find
352will return
353.Dv NULL
354when there is no entry or match in the list; however, this is not considered
355a failure mode and no error value is available.
356.Pp
357Functions returning a integer success valuye will return
358.Dv 0
359on success, or
360.Dv -1
361on failure.
362If a failure is returned, the list error access method,
363.Fn memstat_mtl_geterror ,
364may be used to retrieve the error state.
365The string representation of the error may be retrieved using
366.Fn memstat_strerror .
367Possible error values are:
368.Pp
369.Bl -tag -width "MEMSTAT_ERROR_TOOMANYCPUS" -compact -offset wee
370.It Dv MEMSTAT_ERROR_UNDEFINED
371Undefined error.  Occurs if
372.Fn memstat_mtl_geterror
373is called on a list before an error associated with the list has occurred.
374.It Dv MEMSTAT_ERROR_NOMEMORY
375Insufficient memory.  Occurs if library calls to
376.Xr malloc 3
377fail, or if a system call to retrieve kernel statistics fails with
378.Er ENOMEM .
379.It Dv MEMSTAT_ERROR_VERSION
380Returned if the current version of
381.Nm
382is unable to interpret the statistics data returned by the kernel due to an
383explicit version mismatch, or to differences in data structures that cannot
384be reconciled.
385.It Dv MEMSTAT_ERROR_PERMISSION
386Returned if a statistics source returns
387.Va errno
388values of
389.Dv EACCES
390or
391.Dv EPERM .
392.It Dv MEMSTAT_ERROR_TOOMANYCPUS
393Returned if the compile-time limit on the number of CPUs in
394.Nm
395is lower than the number of CPUs returned by a statistics data source.
396.It Dv MEMSTAT_ERROR_DATAERROR
397Returned if
398.Nm
399is unable to interpret statistics data returned by the data source, even
400though there does not appear to be a version problem.
401.El
402.Pp
403Finally, functions returning data from a
404.Dt struct memory_type
405pointer are not permitted to fail, and directly return either a statistic
406or pointer to a string.
407.Sh EXAMPLES
408Create a memory type list, query the
409.Xr uma 9
410memory allocator for available statistics, and print out the number of
411allocations performed by the
412.Dv Mbuf
413zone.
414.Bd -literal -offset indent
415struct memory_type_list *mtlp;
416struct memory_type *mtp;
417uint64_t mbuf_count;
418
419mtlp = memstat_mtl_alloc();
420if (mtlp == NULL)
421    err(-1, "memstat_mtl_alloc");
422if (memstat_sysctl_uma(mtlp, 0) < 0)
423    err(-1, "memstat_sysctl_uma");
424mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, "Mbuf");
425if (mtp == NULL)
426    errx(-1, "memstat_mtl_find: Mbuf not found");
427mbuf_count = memstat_get_count(mtp);
428memstat_mtl_free(mtlp);
429
430printf("Mbufs: %llu\\n", (unsigned long long)mbuf_count);
431.Ed
432.Sh SEE ALSO
433.Xr malloc 9 ,
434.Xr uma 9
435.Sh HISTORY
436The
437.Nm libmemstat
438library appeared in
439.Fx 6.0 .
440.Sh AUTHORS
441The kernel memory allocator changes necessary to support a general purpose
442monitoring library, along with the library, were written by
443.An Robert Watson Aq [email protected]
444.Sh BUGS
445.Nm
446cannot yet extract statistics from kernel core dumps, although this should be
447straight forward to implement.
448.Pp
449Once a memory type is present on a memory type list, it will not be removed
450even if the kernel no longer presents information on the type via its
451monitoring interfaces.
452In order to flush removed memory types, it is necessary to free the entire
453list and allocate a new one.
454