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