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