1.\" $NetBSD: vmem.9,v 1.20 2020/06/16 01:29:00 thorpej Exp $ 2.\" 3.\" Copyright (c)2006 YAMAMOTO Takashi, 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" SUCH DAMAGE. 26.\" 27.\" ------------------------------------------------------------ 28.Dd June 15, 2020 29.Dt VMEM 9 30.Os 31.\" ------------------------------------------------------------ 32.Sh NAME 33.Nm vmem 34.Nd virtual memory allocator 35.\" ------------------------------------------------------------ 36.Sh SYNOPSIS 37.In sys/vmem.h 38.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 39.Ft vmem_t * 40.Fn vmem_create \ 41"const char *name" "vmem_addr_t base" "vmem_size_t size" "vmem_size_t quantum" \ 42"int (*allocfn)(void *, vmem_size_t, vm_flag_t, vmem_addr_t *)" \ 43"void (*freefn)(void *, vmem_addr_t, vmem_size_t)" \ 44"void *arg" "vmem_size_t qcache_max" "vm_flag_t flags" "int ipl" 45.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 46.Ft vmem_t * 47.Fn vmem_xcreate \ 48"const char *name" "vmem_addr_t base" "vmem_size_t size" "vmem_size_t quantum" \ 49"int (*allocfn)(void *, vmem_size_t, vmem_size_t *, vm_flag_t, vmem_addr_t *)" \ 50"void (*freefn)(void *, vmem_addr_t, vmem_size_t)" \ 51"void *arg" "vmem_size_t qcache_max" "vm_flag_t flags" "int ipl" 52.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 53.Ft int 54.Fn vmem_add \ 55"vmem_t *vm" "vmem_addr_t addr" "vmem_size_t size" "vm_flag_t flags" 56.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 57.Ft int 58.Fn vmem_xalloc \ 59"vmem_t *vm" "vmem_size_t size" "vmem_size_t align" \ 60"vmem_size_t phase" "vmem_size_t nocross" "vmem_addr_t minaddr" \ 61"vmem_addr_t maxaddr" "vm_flag_t flags" "vmem_addr_t *addrp" 62.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 63.Ft void 64.Fn vmem_xfree "vmem_t *vm" "vmem_addr_t addr" "vmem_size_t size" 65.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 66.Ft void 67.Fn vmem_xfreeall "vmem_t *vm" 68.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 69.Ft int 70.Fn vmem_alloc "vmem_t *vm" "vmem_size_t size" "vm_flag_t flags" "vmem_addr_t *addrp" 71.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 72.Ft void 73.Fn vmem_free "vmem_t *vm" "vmem_addr_t addr" "vmem_size_t size" 74.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 75.Ft void 76.Fn vmem_destroy "vmem_t *vm" 77.\" ------------------------------------------------------------ 78.Sh DESCRIPTION 79The 80.Nm 81is a general purpose resource allocator. 82Despite its name, it can be used for arbitrary resources 83other than virtual memory. 84.Pp 85.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 86.Fn vmem_create 87creates a new vmem arena. 88.Bl -tag -offset indent -width qcache_max 89.It Fa name 90The string to describe the vmem. 91.It Fa base 92The start address of the initial span. 93Pass 94.Dv 0 95if no initial span is required. 96.It Fa size 97The size of the initial span. 98Pass 99.Dv 0 100if no initial span is required. 101.It Fa quantum 102The smallest unit of allocation. 103.It Fa allocfn 104The callback function used to import spans from the backend arena. 105Set both 106.Fa allocfn 107and 108.Fa freefn 109to 110.Dv NULL 111to disable automatic imports. 112.Nm 113calls 114.Fo "(*allocfn)" 115.Fa arg 116.Fa size 117.Fa flags 118.Fa "&addrp" 119.Fc 120to import a span of size at least 121.Fa size . 122.Fa allocfn 123must accept the same 124.Fa flags 125as 126.Fn vmem_alloc . 127.Fa allocfn 128must return 129.Dv ENOMEM 130to indicate failure, or 0 on success. 131If 132.Fa allocfn 133succeeds, it must write the starting address of the imported span to 134.Fa addrp . 135.It Fa freefn 136The callback function used to free spans to the backend arena. 137.Fa freefn 138may be 139.Dv NULL 140even if 141.Fa allocfn 142is not 143.Dv NULL . 144.Nm 145calls 146.Fn "(*freefn)" arg addr size 147to return to 148.Fa arg 149a span of size 150.Fa size , 151starting at 152.Fa addr , 153that was previously allocated by 154.Fa allocfn . 155.It Fa arg 156The backend arena. 157.Fa arg 158may be 159.Dv NULL . 160.Nm 161passes 162.Fa arg 163as the first argument of 164.Fa allocfn 165and 166.Fa freefn . 167.It Fa qcache_max 168The largest size of allocations which can be served by quantum cache. 169It is merely a hint and can be ignored. 170.It Fa flags 171Either of: 172.Bl -tag -width VM_NOSLEEP 173.It Dv VM_SLEEP 174If the allocation cannot be satisfied immediately, sleep until enough 175resources are available. 176.It Dv VM_NOSLEEP 177Don't sleep. 178Immediately return 179.Dv NULL 180if there are not enough resources available. 181.El 182.It Fa ipl 183Interrupt level to be blocked for allocating from vmem. 184.El 185.Pp 186.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 187.Fn vmem_xcreate 188creates a new vmem arena. 189.Bl -tag -offset indent -width qcache_max 190.It Fa name 191The string to describe the vmem. 192.It Fa base 193The start address of the initial span. 194Pass 195.Dv 0 196if no initial span is required. 197.It Fa size 198The size of the initial span. 199Pass 200.Dv 0 201if no initial span is required. 202.It Fa quantum 203The smallest unit of allocation. 204.It Fa allocfn 205The callback function used to import spans from the backend arena. 206Set both 207.Fa allocfn 208and 209.Fa freefn 210to 211.Dv NULL 212to disable automatic imports. 213.Nm 214calls 215.Fo "(*allocfn)" 216.Fa arg 217.Fa size 218.Fa "&actualsize" 219.Fa flags 220.Fa "&addrp" 221.Fc 222to import a span of size at least 223.Fa size . 224.Fa allocfn 225must accept the same 226.Fa flags 227as 228.Fn vmem_alloc . 229.Fa allocfn 230must return 231.Dv ENOMEM 232to indicate failure, or 0 on success. 233If 234.Fa allocfn 235succeeds, it must write the actual size of the allocation to 236.Fa actualsize 237and the starting address of the imported span to 238.Fa addrp . 239The actual size will always be greater than or equal to the requested size. 240.It Fa freefn 241The callback function used to free spans to the backend arena. 242.Fa freefn 243may be 244.Dv NULL 245even if 246.Fa allocfn 247is not 248.Dv NULL . 249.Nm 250calls 251.Fn "(*freefn)" arg addr size 252to return to 253.Fa arg 254a span of size 255.Fa size , 256starting at 257.Fa addr , 258that was previously allocated by 259.Fa allocfn . 260.It Fa arg 261The backend arena. 262.Fa arg 263may be 264.Dv NULL . 265.Nm 266passes 267.Fa arg 268as the first argument of 269.Fa allocfn 270and 271.Fa freefn . 272.It Fa qcache_max 273The largest size of allocations which can be served by quantum cache. 274It is merely a hint and can be ignored. 275.It Fa flags 276Either of: 277.Bl -tag -width VM_NOSLEEP 278.It Dv VM_SLEEP 279If the allocation cannot be satisfied immediately, sleep until enough 280resources are available. 281.It Dv VM_NOSLEEP 282Don't sleep. 283Immediately return 284.Dv NULL 285if there are not enough resources available. 286.El 287.It Fa ipl 288Interrupt level to be blocked for allocating from vmem. 289.El 290.Pp 291.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 292.Fn vmem_add 293adds a span of size 294.Fa size 295starting at 296.Fa addr 297to the arena. 298Returns 2990 300on success, 301.Dv ENOMEM 302on failure. 303.Bl -tag -offset indent -width flags 304.It Fa flags 305Either of: 306.Bl -tag -width VM_NOSLEEP 307.It Dv VM_SLEEP 308If the allocation cannot be satisfied immediately, sleep until enough 309resources are available. 310.It Dv VM_NOSLEEP 311Don't sleep. 312Immediately return 313.Dv ENOMEM 314if there are not enough resources available. 315.El 316.El 317.Pp 318.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 319.Fn vmem_xalloc 320allocates a resource from the arena. 321.Bl -tag -offset indent -width nocross 322.It Fa vm 323The arena which we allocate from. 324.It Fa size 325Specify the size of the allocation. 326.It Fa align 327If zero, don't care about the alignment of the allocation. 328Otherwise, request a resource segment starting at 329offset 330.Fa phase 331from an 332.Fa align 333aligned boundary. 334.It Fa phase 335See the above description of 336.Fa align . 337If 338.Fa align 339is zero, 340.Fa phase 341must be zero. 342Otherwise, 343.Fa phase 344must be smaller than 345.Fa align . 346.It Fa nocross 347Request a resource which doesn't cross 348.Fa nocross 349aligned boundary. 350.It Fa minaddr 351Specify the minimum address which can be allocated, or 352.Dv VMEM_ADDR_MIN 353if the caller does not care. 354.It Fa maxaddr 355Specify the maximum address which can be allocated, or 356.Dv VMEM_ADDR_MAX 357if the caller does not care. 358.It Fa flags 359A bitwise OR of an allocation strategy and a sleep flag. 360.Pp 361The allocation strategy must be one of: 362.Bl -tag -width VM_INSTANTFIT 363.It Dv VM_BESTFIT 364Prefer space efficiency. 365.It Dv VM_INSTANTFIT 366Prefer performance. 367.El 368.Pp 369The sleep flag must be one of: 370.Bl -tag -width VM_NOSLEEP 371.It Dv VM_SLEEP 372If the allocation cannot be satisfied immediately, sleep until enough 373resources are available. 374.It Dv VM_NOSLEEP 375Don't sleep. 376Immediately return 377.Dv ENOMEM 378if there are not enough resources available. 379.El 380.It Fa addrp 381On success, if 382.Fa addrp 383is not 384.Dv NULL , 385.Fn vmem_xalloc 386overwrites it with the start address of the allocated span. 387.El 388.Pp 389.\" ------------------------------------------------------------ 390.Fn vmem_xfree 391frees resource allocated by 392.Fn vmem_xalloc 393to the arena. 394.Bl -tag -offset indent -width addr 395.It Fa vm 396The arena which we free to. 397.It Fa addr 398The resource being freed. 399It must have been allocated via 400.Fn vmem_xalloc . 401Notably, it must not have been allocated via 402.Fn vmem_alloc . 403Otherwise, the behaviour is undefined. 404.It Fa size 405The size of the resource being freed. 406It must be the same as the 407.Fa size 408argument used for 409.Fn vmem_xalloc . 410.El 411.Pp 412.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 413.Fn vmem_xfreeall 414frees all resources that have been allocated by 415.Fn vmem_xalloc 416to the arena. 417.Bl -tag -offset indent -width addr 418.It Fa vm 419The arena which we free to. 420Note that this function is may not be used on arenas 421where resources have been allocated using 422.Fn vmem_alloc 423or arenas that have a quantum cache 424.Po 425i.e. were created with a non-zero 426.Fa qcache_max 427.Pc . 428.El 429.Pp 430.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 431.Fn vmem_alloc 432allocates a resource from the arena. 433.Bl -tag -offset indent -width flags 434.It Fa vm 435The arena which we allocate from. 436.It Fa size 437Specify the size of the allocation. 438.It Fa flags 439A bitwise OR of an allocation strategy and a sleep flag. 440.Pp 441The allocation strategy must be one of: 442.Bl -tag -width VM_INSTANTFIT 443.It Dv VM_BESTFIT 444Prefer space efficiency. 445.It Dv VM_INSTANTFIT 446Prefer performance. 447.El 448.Pp 449The sleep flag must be one of: 450.Bl -tag -width VM_NOSLEEP 451.It Dv VM_SLEEP 452If the allocation cannot be satisfied immediately, sleep until enough 453resources are available. 454.It Dv VM_NOSLEEP 455Don't sleep. 456Immediately return 457.Dv ENOMEM 458if there are not enough resources available. 459.El 460.It Fa addrp 461On success, if 462.Fa addrp 463is not 464.Dv NULL , 465.Fn vmem_alloc 466overwrites it with the start address of the allocated span. 467.El 468.Pp 469.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 470.Fn vmem_free 471frees resource allocated by 472.Fn vmem_alloc 473to the arena. 474.Bl -tag -offset indent -width addr 475.It Fa vm 476The arena which we free to. 477.It Fa addr 478The resource being freed. 479It must have been allocated via 480.Fn vmem_alloc . 481Notably, it must not have been allocated via 482.Fn vmem_xalloc . 483Otherwise, the behaviour is undefined. 484.It Fa size 485The size of the resource being freed. 486It must be the same as the 487.Fa size 488argument used for 489.Fn vmem_alloc . 490.El 491.Pp 492.\" ------------------------------------------------------------ 493.Fn vmem_destroy 494destroys a vmem arena. 495.Bl -tag -offset indent -width vm 496.It Fa vm 497The vmem arena being destroyed. 498The caller must ensure that no one will use it anymore. 499.El 500.\" ------------------------------------------------------------ 501.Sh RETURN VALUES 502.Fn vmem_create 503return a pointer to the newly allocated vmem_t. 504Otherwise, it returns 505.Dv NULL . 506.Pp 507On success, 508.Fn vmem_xalloc 509and 510.Fn vmem_alloc 511return 0. 512Otherwise, 513.Dv ENOMEM 514is returned. 515.\" ------------------------------------------------------------ 516.Sh CODE REFERENCES 517The 518.Nm 519subsystem is implemented within the file 520.Pa sys/kern/subr_vmem.c . 521.\" ------------------------------------------------------------ 522.Sh SEE ALSO 523.Xr intro 9 , 524.Xr kmem 9 , 525.Xr memoryallocators 9 , 526.Xr uvm 9 527.Rs 528.%A Jeff Bonwick 529.%A Jonathan Adams 530.%T "Magazines and Vmem: Extending the Slab Allocator to Many CPUs and Arbitrary Resources" 531.%J "2001 USENIX Annual Technical Conference" 532.%D 2001 533.Re 534.\" ------------------------------------------------------------ 535.Sh AUTHORS 536This implementation of 537.Nm 538was written by 539.An YAMAMOTO Takashi . 540.Sh BUGS 541.Nm 542relies on 543.Xr malloc 9 , 544.Xr pool 9 , 545and 546.Xr RUN_ONCE 9 , 547so it cannot be used as early during system bootstrap as 548.Xr extent 9 . 549