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 Memory Type List Management Functions 39.Ft struct memory_type_list * 40.Fn memstat_mtl_alloc "void" 41.Ft struct memory_type * 42.Fn memstat_mtl_first "struct memory_type_list *list" 43.Ft struct memory_type * 44.Fn memstat_mtl_next "struct memory_type *mtp" 45.Ft struct memory_type * 46.Fn memstat_mtl_find "struct memory_type_list *list" "int allocator" "const char *name" 47.Ft void 48.Fn memstat_mtl_free "struct memory_type_list *list" 49.Ss Allocator Query Functions 50.Ft int 51.Fn memstat_sysctl_all "struct memory_type_list *list" "int flags" 52.Ft int 53.Fn memstat_sysctl_malloc "struct memory_type_list *list" "int flags" 54.Ft int 55.Fn memstat_sysctl_uma "struct memory_type_list *list" "int flags" 56.Ss Memory Type Accessor Methods 57.Ft const char * 58.Fn memstat_get_name "const struct memory_type *mtp" 59.Ft int 60.Fn memstat_get_allocator "const struct memory_type *mtp" 61.Ft uint64_t 62.Fn memstat_get_countlimit "const struct memory_type *mtp" 63.Ft uint64_t 64.Fn memstat_get_byteslimit "const struct memory_type *mtp" 65.Ft uint64_t 66.Fn memstat_get_sizemask "const struct memory_type *mtp" 67.Ft uint64_t 68.Fn memstat_get_size "const struct memory_type *mtp" 69.Ft uint64_t 70.Fn memstat_get_memalloced "const struct memory_type *mtp" 71.Ft uint64_t 72.Fn memstat_get_memfreed "const struct memory_type *mtp" 73.Ft uint64_t 74.Fn memstat_get_numallocs "const struct memory_type *mtp" 75.Ft uint64_t 76.Fn memstat_get_numfrees "const struct memory_type *mtp" 77.Ft uint64_t 78.Fn memstat_get_bytes "const struct memory_type *mtp" 79.Ft uint64_t 80.Fn memstat_get_count "const struct memory_type *mtp" 81.Ft uint64_t 82.Fn memstat_get_free "const struct memory_type *mtp" 83.Ft uint64_t 84.Fn memstat_get_failures "const struct memory_type *mtp" 85.Ft void * 86.Fn memstat_get_caller_pointer "const struct memory_type *mtp" "int index" 87.Ft void 88.Fn memstat_set_caller_pointer "struct memory_type *mtp" "int index" "void *value" 89.Ft uint64_t 90.Fn memstat_get_caller_uint64 "const struct memory_type *mtp" "int index" 91.Ft void 92.Fn memstat_set_caller_uint64 "struct memory_type *mtp" "int index" "uint64_t value" 93.Ft uint64_t 94.Fn memstat_get_zonefree "const struct memory_type *mtp" 95.Ft uint64_t 96.Fn memstat_get_percpu_memalloced "const struct memory_type *mtp" "int cpu" 97.Ft uint64_t 98.Fn memstat_get_percpu_memfreed "const struct memory_type *mtp" "int cpu" 99.Ft uint64_t 100.Fn memstat_get_percpu_numallocs "const struct memory_type *mtp" "int cpu" 101.Ft uint64_t 102.Fn memstat_get_percpu_numfrees "const struct memory_type *mtp" "int cpu" 103.Ft uint64_t 104.Fn memstat_get_percpu_sizemask "const struct memory_type *mtp" "int cpu" 105.Ft void * 106.Fn memstat_get_percpu_caller_pointer "const struct memory_type *mtp" "int cpu" "int index" 107.Ft void 108.Fn memstat_set_percpu_caller_pointer "struct memory_type *mtp" "int cpu" "int index" "void *value" 109.Ft uint64_t 110.Fn memstat_get_percpu_caller_uint64 "const struct memory_type *mtp" "int cpu" "int index" 111.Ft void 112.Fn memstat_set_percpu_caller_uint64 "struct memory_type *mtp" "int cpu" "int index" "uint64_t value" 113.Ft uint64_t 114.Fn memstat_get_percpu_free "const struct memory_type *mtp" "int cpu" 115.Sh DESCRIPTION 116.Nm 117provides an interface to retrieve kernel memory allocator statistics, for 118the purposes of debugging and system monitoring, insulating applications 119from implementation details of the allocators, and allowing a tool to 120transparently support multiple allocators. 121.Nm 122supports both retrieving a single statistics snapshot, as well as 123incrementally updating statistics for long-term monitoring. 124.Pp 125.Nm 126describes each memory type using a 127.Vt struct memory_type , 128an opaque memory type accessed by the application using accessor functions 129in the library. 130.Nm 131returns and updates chains of 132.Vt struct memory_type 133via a 134.Vt struct memory_type_list , 135which will be allocated by calling 136.Fn memstat_mtl_alloc , 137and freed on completion using 138.Fn memstat_mtl_free . 139Lists of memory types are populated via calls that query the kernel for 140statistics information; currently: 141.Fn memstat_sysctl_all , 142.Fn memstat_sysctl_uma , 143and 144.Fn memstat_sysctl_malloc . 145Repeated calls will incrementally update the list of memory types, permitting 146tracking over time without recreating all list state. 147Freeing the list will free all memory type data in the list, and so 148invalidates any outstanding pointers to entries in the list. 149.Vt struct memory_type 150entries in the list may be iterated over using 151.Fn memstat_mtl_first 152and 153.fn memstat_mtl_next , 154which respectively return the first entry in a list, and the next entry in a 155list. 156.Fn memstat_mtl_find , 157which will return a pointer to the first entry matching the passed 158parameters. 159.Pp 160A series of accessor methods is provided to access fields of the structure, 161including retrieving statistics and properties, as well as setting of caller 162owned fields. 163Direct application access to the data structure fields is not supported. 164.Ss Library memory_type Fields 165Each 166.Vt struct memory_type 167holds a description of the memory type, including its name and the allocator 168it is managed by, as well as current statistics on use. 169Some statistics are directly measured, others are derived from directly 170measured statistics. 171Certain high level statistics are present across all available allocators, 172such as the number of allocation and free operations; other measurements, 173such as the quantity of free items in per-CPU caches, or administrative 174limit on the number of allocations, is available only for specific 175allocators. 176.Ss Caller memory_type Fields 177.Vt struct memory_type 178includes fields to allow the application to store data, in the form of 179pointers and 64-bit integers, with memory types. 180For example, the application author might make use of one of the caller 181pointers to reference a more complex data structure tracking long-term 182behavior of the memory type, or a window system object that is used to 183render the state of the memory type. 184General and per-CPU storage is provided with each 185.Vt struct memory_type 186in the form of an array of pointers and integers. 187The array entries are accessed via the 188.Fa index 189argument to the get and set accessor methods. 190Possible values of 191.Fa index 192range between 193.Dv 0 194and 195.Dv MEMSTAT_MAXCALLER . 196.Pp 197Caller-owned fields are initialized to 198.Dv 0 199or 200.Dv NULL 201when a new 202.Vt struct memory_type 203is allocated and attached to a memory type list; these fields retain their 204values across queries that update library-owned fields. 205.Ss Allocator Types 206Currently, 207.Nm 208supports two kernel allocators: 209.Dv ALLOCATOR_UMA 210for 211.Xr uma 9 , 212and 213.Dv ALLOCATOR_MALLOC 214for 215.Xr malloc 9 . 216These values may be passed to 217.Fn memstat_mtl_find , 218and will be returned by 219.Fn memstat_get_allocator . 220Two additional constants in the allocator name space are defined: 221.Dv ALLOCATOR_UNKNOWN , 222which will only be returned as a result of a library error, and 223.Dv ALLOCATOR_ANY , 224which can be used to specify that returning types matching any allocator is 225permittible from 226.Fn memstat_mtl_find . 227.Sh EXAMPLES 228Create a memory type list, query the 229.Xr uma 9 230memory allocator for available statistics, and print out the number of 231allocations performed by the 232.Dv Mbuf 233zone. 234.Bd -literal -offset indent 235struct memory_type_list *mtlp; 236struct memory_type *mtp; 237uint64_t mbuf_count; 238 239mtlp = memstat_mtl_alloc(); 240if (mtlp == NULL) 241 err(-1, "memstat_mtl_alloc"); 242if (memstat_sysctl_uma(mtlp, 0) < 0) 243 err(-1, "memstat_sysctl_uma"); 244mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, "Mbuf"); 245if (mtp == NULL) 246 errx(-1, "memstat_mtl_find: Mbuf not found"); 247mbuf_count = memstat_get_count(mtp); 248memstat_mtl_free(mtlp); 249 250printf("Mbufs: %llu\\n", (unsigned long long)mbuf_count); 251.Ed 252.Sh SEE ALSO 253.Xr malloc 9 , 254.Xr uma 9 255.Sh HISTORY 256The 257.Nm memstat 258library appeared in 259.Fx 6.0 . 260.Sh AUTHORS 261The kernel memory allocator changes necessary to support a general purpose 262monitoring library, along with the library, were written by 263.An Robert Watson Aq [email protected] 264.Sh BUGS 265.Nm 266cannot yet extract statistics from kernel core dumps, although this should be 267straight forward to implement. 268.Pp 269Once a memory type is present on a memory type list, it will not be removed 270even if the kernel no longer presents information on the type via its 271monitoring interfaces. 272In order to flush removed memory types, it is necessary to free the entire 273list and allocate a new one. 274