1.\" $NetBSD: vmem.9,v 1.19 2019/11/06 11:55:18 wiz 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 November 5, 2019 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 int 67.Fn vmem_alloc "vmem_t *vm" "vmem_size_t size" "vm_flag_t flags" "vmem_addr_t *addrp" 68.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 69.Ft void 70.Fn vmem_free "vmem_t *vm" "vmem_addr_t addr" "vmem_size_t size" 71.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 72.Ft void 73.Fn vmem_destroy "vmem_t *vm" 74.\" ------------------------------------------------------------ 75.Sh DESCRIPTION 76The 77.Nm 78is a general purpose resource allocator. 79Despite its name, it can be used for arbitrary resources 80other than virtual memory. 81.Pp 82.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 83.Fn vmem_create 84creates a new vmem arena. 85.Bl -tag -offset indent -width qcache_max 86.It Fa name 87The string to describe the vmem. 88.It Fa base 89The start address of the initial span. 90Pass 91.Dv 0 92if no initial span is required. 93.It Fa size 94The size of the initial span. 95Pass 96.Dv 0 97if no initial span is required. 98.It Fa quantum 99The smallest unit of allocation. 100.It Fa allocfn 101The callback function used to import spans from the backend arena. 102Set both 103.Fa allocfn 104and 105.Fa freefn 106to 107.Dv NULL 108to disable automatic imports. 109.Nm 110calls 111.Fo "(*allocfn)" 112.Fa arg 113.Fa size 114.Fa flags 115.Fa "&addrp" 116.Fc 117to import a span of size at least 118.Fa size . 119.Fa allocfn 120must accept the same 121.Fa flags 122as 123.Fn vmem_alloc . 124.Fa allocfn 125must return 126.Dv ENOMEM 127to indicate failure, or 0 on success. 128If 129.Fa allocfn 130succeeds, it must write the starting address of the imported span to 131.Fa addrp . 132.It Fa freefn 133The callback function used to free spans to the backend arena. 134.Fa freefn 135may be 136.Dv NULL 137even if 138.Fa allocfn 139is not 140.Dv NULL . 141.Nm 142calls 143.Fn "(*freefn)" arg addr size 144to return to 145.Fa arg 146a span of size 147.Fa size , 148starting at 149.Fa addr , 150that was previously allocated by 151.Fa allocfn . 152.It Fa arg 153The backend arena. 154.Fa arg 155may be 156.Dv NULL . 157.Nm 158passes 159.Fa arg 160as the first argument of 161.Fa allocfn 162and 163.Fa freefn . 164.It Fa qcache_max 165The largest size of allocations which can be served by quantum cache. 166It is merely a hint and can be ignored. 167.It Fa flags 168Either of: 169.Bl -tag -width VM_NOSLEEP 170.It Dv VM_SLEEP 171If the allocation cannot be satisfied immediately, sleep until enough 172resources are available. 173.It Dv VM_NOSLEEP 174Don't sleep. 175Immediately return 176.Dv NULL 177if there are not enough resources available. 178.El 179.It Fa ipl 180Interrupt level to be blocked for allocating from vmem. 181.El 182.Pp 183.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 184.Fn vmem_xcreate 185creates a new vmem arena. 186.Bl -tag -offset indent -width qcache_max 187.It Fa name 188The string to describe the vmem. 189.It Fa base 190The start address of the initial span. 191Pass 192.Dv 0 193if no initial span is required. 194.It Fa size 195The size of the initial span. 196Pass 197.Dv 0 198if no initial span is required. 199.It Fa quantum 200The smallest unit of allocation. 201.It Fa allocfn 202The callback function used to import spans from the backend arena. 203Set both 204.Fa allocfn 205and 206.Fa freefn 207to 208.Dv NULL 209to disable automatic imports. 210.Nm 211calls 212.Fo "(*allocfn)" 213.Fa arg 214.Fa size 215.Fa "&actualsize" 216.Fa flags 217.Fa "&addrp" 218.Fc 219to import a span of size at least 220.Fa size . 221.Fa allocfn 222must accept the same 223.Fa flags 224as 225.Fn vmem_alloc . 226.Fa allocfn 227must return 228.Dv ENOMEM 229to indicate failure, or 0 on success. 230If 231.Fa allocfn 232succeeds, it must write the actual size of the allocation to 233.Fa actualsize 234and the starting address of the imported span to 235.Fa addrp . 236The actual size will always be greater than or equal to the requested size. 237.It Fa freefn 238The callback function used to free spans to the backend arena. 239.Fa freefn 240may be 241.Dv NULL 242even if 243.Fa allocfn 244is not 245.Dv NULL . 246.Nm 247calls 248.Fn "(*freefn)" arg addr size 249to return to 250.Fa arg 251a span of size 252.Fa size , 253starting at 254.Fa addr , 255that was previously allocated by 256.Fa allocfn . 257.It Fa arg 258The backend arena. 259.Fa arg 260may be 261.Dv NULL . 262.Nm 263passes 264.Fa arg 265as the first argument of 266.Fa allocfn 267and 268.Fa freefn . 269.It Fa qcache_max 270The largest size of allocations which can be served by quantum cache. 271It is merely a hint and can be ignored. 272.It Fa flags 273Either of: 274.Bl -tag -width VM_NOSLEEP 275.It Dv VM_SLEEP 276If the allocation cannot be satisfied immediately, sleep until enough 277resources are available. 278.It Dv VM_NOSLEEP 279Don't sleep. 280Immediately return 281.Dv NULL 282if there are not enough resources available. 283.El 284.It Fa ipl 285Interrupt level to be blocked for allocating from vmem. 286.El 287.Pp 288.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 289.Fn vmem_add 290adds a span of size 291.Fa size 292starting at 293.Fa addr 294to the arena. 295Returns 2960 297on success, 298.Dv ENOMEM 299on failure. 300.Bl -tag -offset indent -width flags 301.It Fa flags 302Either of: 303.Bl -tag -width VM_NOSLEEP 304.It Dv VM_SLEEP 305If the allocation cannot be satisfied immediately, sleep until enough 306resources are available. 307.It Dv VM_NOSLEEP 308Don't sleep. 309Immediately return 310.Dv ENOMEM 311if there are not enough resources available. 312.El 313.El 314.Pp 315.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 316.Fn vmem_xalloc 317allocates a resource from the arena. 318.Bl -tag -offset indent -width nocross 319.It Fa vm 320The arena which we allocate from. 321.It Fa size 322Specify the size of the allocation. 323.It Fa align 324If zero, don't care about the alignment of the allocation. 325Otherwise, request a resource segment starting at 326offset 327.Fa phase 328from an 329.Fa align 330aligned boundary. 331.It Fa phase 332See the above description of 333.Fa align . 334If 335.Fa align 336is zero, 337.Fa phase 338must be zero. 339Otherwise, 340.Fa phase 341must be smaller than 342.Fa align . 343.It Fa nocross 344Request a resource which doesn't cross 345.Fa nocross 346aligned boundary. 347.It Fa minaddr 348Specify the minimum address which can be allocated, or 349.Dv VMEM_ADDR_MIN 350if the caller does not care. 351.It Fa maxaddr 352Specify the maximum address which can be allocated, or 353.Dv VMEM_ADDR_MAX 354if the caller does not care. 355.It Fa flags 356A bitwise OR of an allocation strategy and a sleep flag. 357.Pp 358The allocation strategy must be one of: 359.Bl -tag -width VM_INSTANTFIT 360.It Dv VM_BESTFIT 361Prefer space efficiency. 362.It Dv VM_INSTANTFIT 363Prefer performance. 364.El 365.Pp 366The sleep flag must be one of: 367.Bl -tag -width VM_NOSLEEP 368.It Dv VM_SLEEP 369If the allocation cannot be satisfied immediately, sleep until enough 370resources are available. 371.It Dv VM_NOSLEEP 372Don't sleep. 373Immediately return 374.Dv ENOMEM 375if there are not enough resources available. 376.El 377.It Fa addrp 378On success, if 379.Fa addrp 380is not 381.Dv NULL , 382.Fn vmem_xalloc 383overwrites it with the start address of the allocated span. 384.El 385.Pp 386.\" ------------------------------------------------------------ 387.Fn vmem_xfree 388frees resource allocated by 389.Fn vmem_xalloc 390to the arena. 391.Bl -tag -offset indent -width addr 392.It Fa vm 393The arena which we free to. 394.It Fa addr 395The resource being freed. 396It must have been allocated via 397.Fn vmem_xalloc . 398Notably, it must not have been allocated via 399.Fn vmem_alloc . 400Otherwise, the behaviour is undefined. 401.It Fa size 402The size of the resource being freed. 403It must be the same as the 404.Fa size 405argument used for 406.Fn vmem_xalloc . 407.El 408.Pp 409.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 410.Fn vmem_alloc 411allocates a resource from the arena. 412.Bl -tag -offset indent -width flags 413.It Fa vm 414The arena which we allocate from. 415.It Fa size 416Specify the size of the allocation. 417.It Fa flags 418A bitwise OR of an allocation strategy and a sleep flag. 419.Pp 420The allocation strategy must be one of: 421.Bl -tag -width VM_INSTANTFIT 422.It Dv VM_BESTFIT 423Prefer space efficiency. 424.It Dv VM_INSTANTFIT 425Prefer performance. 426.El 427.Pp 428The sleep flag must be one of: 429.Bl -tag -width VM_NOSLEEP 430.It Dv VM_SLEEP 431If the allocation cannot be satisfied immediately, sleep until enough 432resources are available. 433.It Dv VM_NOSLEEP 434Don't sleep. 435Immediately return 436.Dv ENOMEM 437if there are not enough resources available. 438.El 439.It Fa addrp 440On success, if 441.Fa addrp 442is not 443.Dv NULL , 444.Fn vmem_alloc 445overwrites it with the start address of the allocated span. 446.El 447.Pp 448.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 449.Fn vmem_free 450frees resource allocated by 451.Fn vmem_alloc 452to the arena. 453.Bl -tag -offset indent -width addr 454.It Fa vm 455The arena which we free to. 456.It Fa addr 457The resource being freed. 458It must have been allocated via 459.Fn vmem_alloc . 460Notably, it must not have been allocated via 461.Fn vmem_xalloc . 462Otherwise, the behaviour is undefined. 463.It Fa size 464The size of the resource being freed. 465It must be the same as the 466.Fa size 467argument used for 468.Fn vmem_alloc . 469.El 470.Pp 471.\" ------------------------------------------------------------ 472.Fn vmem_destroy 473destroys a vmem arena. 474.Bl -tag -offset indent -width vm 475.It Fa vm 476The vmem arena being destroyed. 477The caller must ensure that no one will use it anymore. 478.El 479.\" ------------------------------------------------------------ 480.Sh RETURN VALUES 481.Fn vmem_create 482return a pointer to the newly allocated vmem_t. 483Otherwise, it returns 484.Dv NULL . 485.Pp 486On success, 487.Fn vmem_xalloc 488and 489.Fn vmem_alloc 490return 0. 491Otherwise, 492.Dv ENOMEM 493is returned. 494.\" ------------------------------------------------------------ 495.Sh CODE REFERENCES 496The 497.Nm 498subsystem is implemented within the file 499.Pa sys/kern/subr_vmem.c . 500.\" ------------------------------------------------------------ 501.Sh SEE ALSO 502.Xr intro 9 , 503.Xr kmem 9 , 504.Xr memoryallocators 9 , 505.Xr uvm 9 506.Rs 507.%A Jeff Bonwick 508.%A Jonathan Adams 509.%T "Magazines and Vmem: Extending the Slab Allocator to Many CPUs and Arbitrary Resources" 510.%J "2001 USENIX Annual Technical Conference" 511.%D 2001 512.Re 513.\" ------------------------------------------------------------ 514.Sh AUTHORS 515This implementation of 516.Nm 517was written by 518.An YAMAMOTO Takashi . 519.Sh BUGS 520.Nm 521relies on 522.Xr malloc 9 , 523.Xr pool 9 , 524and 525.Xr RUN_ONCE 9 , 526so it cannot be used as early during system bootstrap as 527.Xr extent 9 . 528