1.\" $OpenBSD: cpumem_get.9,v 1.11 2020/08/27 09:29:16 fcambus Exp $ 2.\" 3.\" Copyright (c) 2016 David Gwynne <dlg@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: August 27 2020 $ 18.Dt CPUMEM_GET 9 19.Os 20.Sh NAME 21.Nm cpumem_get , 22.Nm cpumem_put , 23.Nm cpumem_malloc , 24.Nm cpumem_malloc_ncpus , 25.Nm cpumem_free , 26.Nm CPUMEM_BOOT_MEMORY , 27.Nm CPUMEM_BOOT_INITIALIZER , 28.Nm cpumem_enter , 29.Nm cpumem_leave , 30.Nm cpumem_first , 31.Nm cpumem_next , 32.Nm CPUMEM_FOREACH 33.Nd per CPU memory allocations 34.Sh SYNOPSIS 35.In sys/percpu.h 36.Ft struct cpumem * 37.Fn cpumem_get "struct pool *pp" 38.Ft void 39.Fn cpumem_put "struct pool *pp" "struct cpumem *cm" 40.Ft struct cpumem * 41.Fn cpumem_malloc "size_t sz" "int type" 42.Ft struct cpumem * 43.Fn cpumem_malloc_ncpus "struct cpumem *cm" "size_t sz" "int type" 44.Ft void 45.Fn cpumem_free "struct cpumem *cm" "int type" "size_t sz" 46.Fn CPUMEM_BOOT_MEMORY "NAME" "size_t sz" 47.Fn CPUMEM_BOOT_INITIALIZER "NAME" 48.Ft void * 49.Fn cpumem_enter "struct cpumem *cm" 50.Ft void 51.Fn cpumem_leave "struct cpumem *cm" "void *m" 52.Ft void * 53.Fn cpumem_first "struct cpumem_iter *ci" "struct cpumem *cm" 54.Ft void * 55.Fn cpumem_next "struct cpumem_iter *ci" "struct cpumem *cm" 56.Fn CPUMEM_FOREACH "VARNAME" "struct cpumem_iter *ci" "struct cpumem *cm" 57.Sh DESCRIPTION 58The per CPU memory API provides wrappers around the allocation of 59and access to per CPU memory. 60.Pp 61An alternate implementation of the API is provided on uni-processor 62(i.e. when the kernel is not built with 63.Dv MULTIPROCESSOR 64defined) 65systems that provides no overhead compared to direct access to a 66data structure. 67This allows the API to be used without affecting the performance 68on uni-processor systems. 69.Ss Per CPU Memory Allocation and Deallocation 70.Fn cpumem_get 71allocates memory for each CPU from the 72.Fa pp 73pool. 74The memory will be zeroed on allocation. 75.Pp 76.Fn cpumem_put 77returns each CPUs memory allocation referenced by 78.Fa cm 79to the 80.Fa pp 81pool. 82.Pp 83.Fn cpumem_malloc 84allocates 85.Fa sz 86bytes of 87.Fa type 88memory for each CPU using 89.Xr malloc 9 . 90The memory will be zeroed on allocation. 91.Pp 92.Fn cpumem_free 93returns each CPU's memory allocation referenced by 94.Fa cm 95to the system using 96.Xr free 9 . 97The same object size and type originally provided to 98.Fn cpumem_malloc 99must be specified by 100.Fa sz 101and 102.Fa type 103respectively. 104.Pp 105.Fn cpumem_get 106and 107.Fn cpumem_malloc 108may only be used after all the CPUs in the system have been attached. 109If per CPU memory needs to be available during early boot, 110a cpumem pointer and memory for the boot CPU may be statically 111allocated. 112.Pp 113.Fn CPUMEM_BOOT_MEMORY 114statically allocates memory for use on the boot CPU 115before the other CPUs in the system have been attached. 116The allocation is identified by 117.Fa NAME , 118and provides the number of bytes specified by the 119.Fa sz 120argument. 121The memory will be initialised to zeros. 122.Pp 123.Fn CPUMEM_BOOT_INITIALIZER 124is used to initialise a cpumem pointer with the memory that was previously 125allocated using 126.Fn CPUMEM_BOOT_MEMORY 127and identified by 128.Fa NAME . 129.Pp 130.Fn cpumem_malloc_ncpus 131allocates additional memory for the CPUs that were attached during boot. 132The cpumem structure 133.Fa cm 134must have been initialised with 135.Fn CPUMEM_BOOT_INITIALIZER . 136The same number of bytes originally passed to 137.Fa COUNTERS_BOOT_MEMORY 138must be specified by 139.Fa sz . 140The 141.Fa type 142argument specifies the type of memory that the counters will be 143allocated as via 144.Xr malloc 9 . 145The contents of the memory on the boot CPU will be preserved, while 146the allocations for the additional CPU's will be zeroed on allocation. 147.Pp 148Per CPU memory that has been allocated with 149.Fn CPUMEM_BOOT_MEMORY 150and 151.Fn cpumem_malloc_ncpus 152cannot be deallocated with 153.Fa cpumem_free . 154Any attempt to do so will lead to undefined behaviour. 155.Ss Per CPU Memory Access 156.Fn cpumem_enter 157provides access to the current CPU's memory allocation referenced by 158.Fa cm . 159.Pp 160.Fn cpumem_leave 161indicates the end of access to the current CPU's memory allocation referenced by 162.Fa cm . 163.Ss Per CPU Memory Iterators 164.Fn cpumem_first 165provides access to the first CPU's memory allocation referenced by 166.Fa cm . 167The iterator 168.Fa ci 169may be used in subsequent calls to 170.Fn cpumem_next . 171.Pp 172.Fn cpumem_next 173provides access to the next CPU's memory allocation referenced by 174.Fa cm 175and 176.Fa ci . 177.Pp 178The 179.Fn CPUMEM_FOREACH 180macro iterates over each CPU's memory allocation referenced by 181.Fa cm 182using the iterator 183.Fa ci , 184setting 185.Fa VARNAME 186to each CPU's allocation in turn. 187.Sh CONTEXT 188.Fn cpumem_get , 189.Fn cpumem_put , 190.Fn cpumem_malloc , 191.Fn cpumem_free , 192and 193.Fn cpumem_malloc_ncpus 194may be called during autoconf, or from process context. 195.Pp 196.Fn cpumem_enter , 197.Fn cpumem_leave , 198.Fn cpumem_first , 199.Fn cpumem_next , 200and 201.Fn CPUMEM_FOREACH 202may be called during autoconf, from process context, or from interrupt 203context. 204The per CPU memory API does not provide any locking or serialisation 205of access to each CPU's memory allocation. 206It is up to the caller to provide appropriate locking or serialisation 207around calls to these functions to prevent concurrent access to the 208relevant data structures. 209.Sh RETURN VALUES 210.Fn cpumem_get , 211.Fn cpumem_malloc , 212and 213.Fn cpumem_malloc_ncpus 214will return an opaque cpumem pointer that references each CPU's 215memory allocation. 216.Pp 217.Fn cpumem_enter 218returns a reference to the current CPU's memory allocation. 219.Pp 220.Fn cpumem_first 221returns a reference to the first CPU's memory allocation. 222.Pp 223.Fn cpumem_next 224returns a reference to the next CPU's memory allocation according to the 225iterator 226.Fa ci , 227or 228.Dv NULL 229if the iterator has run out of CPUs. 230.Sh SEE ALSO 231.Xr counters_alloc 9 , 232.Xr malloc 9 , 233.Xr pool_get 9 234.Sh HISTORY 235The per CPU memory API first appeared in 236.Ox 6.1 . 237.Sh AUTHORS 238The per CPU memory API was written by 239.An David Gwynne Aq Mt dlg@openbsd.org . 240