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