1.\" $NetBSD: kmem.9,v 1.26 2020/06/19 07:25:20 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 June 19, 2020 29.Dt KMEM 9 30.Os 31.\" ------------------------------------------------------------ 32.Sh NAME 33.Nm kmem 34.Nd kernel wired memory allocator 35.\" ------------------------------------------------------------ 36.Sh SYNOPSIS 37.In sys/kmem.h 38.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 39.Ft void * 40.Fn kmem_alloc \ 41"size_t size" "km_flag_t kmflags" 42.Ft void * 43.Fn kmem_zalloc \ 44"size_t size" "km_flag_t kmflags" 45.Ft void 46.Fn kmem_free \ 47"void *p" "size_t size" 48.\" --- 49.Ft void * 50.Fn kmem_intr_alloc \ 51"size_t size" "km_flag_t kmflags" 52.Ft void * 53.Fn kmem_intr_zalloc \ 54"size_t size" "km_flag_t kmflags" 55.Ft void 56.Fn kmem_intr_free \ 57"void *p" "size_t size" 58.\" --- 59.Ft char * 60.Fn kmem_asprintf \ 61"const char *fmt" "..." 62.\" --- 63.Ft char * 64.Fn kmem_strdupsize \ 65"const char *str" "size_t *size" "km_flag_t kmflags" 66.Ft char * 67.Fn kmem_strdup \ 68"const char *str" "km_flag_t kmflags" 69.Ft char * 70.Fn kmem_strndup \ 71"const char *str" "size_t manxlen" "km_flag_t kmflags" 72.Ft void 73.Fn kmem_strfree \ 74"char *str" 75.\" ------------------------------------------------------------ 76.Pp 77.Cd "options KMEM_SIZE" 78.Sh DESCRIPTION 79.Fn kmem_alloc 80allocates kernel wired memory. 81It takes the following arguments. 82.Bl -tag -width kmflags 83.It Fa size 84Specify the size of allocation in bytes. 85.It Fa kmflags 86Either of the following: 87.Bl -tag -width KM_NOSLEEP 88.It Dv KM_SLEEP 89If the allocation cannot be satisfied immediately, sleep until enough 90memory is available. 91If 92.Dv KM_SLEEP 93is specified, then the allocation cannot fail. 94.It Dv KM_NOSLEEP 95Don't sleep. 96Immediately return 97.Dv NULL 98if there is not enough memory available. 99It should only be used when failure to allocate will not have harmful, 100user-visible effects. 101.Pp 102.Bf -symbolic 103Use of 104.Dv KM_NOSLEEP 105is strongly discouraged as it can create transient, hard to debug failures 106that occur when the system is under memory pressure. 107.Ef 108.Pp 109In situations where it is not possible to sleep, for example because locks 110are held by the caller, the code path should be restructured to allow the 111allocation to be made in another place. 112.El 113.El 114.Pp 115The contents of allocated memory are uninitialized. 116.Pp 117Unlike Solaris, kmem_alloc(0, flags) is illegal. 118.Pp 119.\" ------------------------------------------------------------ 120.Fn kmem_zalloc 121is the equivalent of 122.Fn kmem_alloc , 123except that it initializes the memory to zero. 124.Pp 125.\" ------------------------------------------------------------ 126.Fn kmem_asprintf 127functions as the well known 128.Fn asprintf 129function, but allocates memory using 130.Fn kmem_alloc . 131This routine can sleep during allocation. 132The size of the allocated area is the length of the returned character string, plus one (for the NUL terminator). 133This must be taken into consideration when freeing the returned area with 134.Fn kmem_free . 135.Pp 136.\" ------------------------------------------------------------ 137.Fn kmem_free 138frees kernel wired memory allocated by 139.Fn kmem_alloc 140or 141.Fn kmem_zalloc 142so that it can be used for other purposes. 143It takes the following arguments. 144.Bl -tag -width kmflags 145.It Fa p 146The pointer to the memory being freed. 147It must be the one returned by 148.Fn kmem_alloc 149or 150.Fn kmem_zalloc . 151.It Fa size 152The size of the memory being freed, in bytes. 153It must be the same as the 154.Fa size 155argument used for 156.Fn kmem_alloc 157or 158.Fn kmem_zalloc 159when the memory was allocated. 160.El 161.Pp 162Freeing 163.Dv NULL 164is illegal. 165.Pp 166.\" ------------------------------------------------------------ 167.Fn kmem_intr_alloc , 168.Fn kmem_intr_zalloc 169and 170.Fn kmem_intr_free 171are the equivalents of the above kmem routines which can be called 172from the interrupt context. 173These routines are for the special cases. 174Normally, 175.Xr pool_cache 9 176should be used for memory allocation from interrupt context. 177.Pp 178The 179.Fn kmem_strdupsize 180function is a utility function that can be used to copy the string in the 181.Fa str 182argument to a new buffer allocated using 183.Fn kmem_alloc 184and optionally return the size of the allocation (the length of the string 185plus the trailing 186.Dv NUL ) 187in the 188.Fa size 189argument if that is not 190.Dv NULL . 191.Pp 192The 193.Fn kmem_strdup 194function is a simplified version of 195.Fn kmem_strdupsize 196that does not return the size of the allocation. 197.Pp 198The 199.Fn kmem_strndup 200function is variation of 201.Fn kmem_strdup 202that copies at most 203.Fa maxlen 204characters from the string 205.Fa str 206always NUL terminating the copied string. 207.Pp 208The 209.Fn kmem_strfree 210function can be used to free a 211.Dv NUL 212terminated string computing the length of the string using 213.Xr strlen 3 214and adding one for the 215.Dv NUL 216and then using 217.Fn kmem_free . 218.\" ------------------------------------------------------------ 219.Sh NOTES 220Making 221.Dv KM_SLEEP 222allocations while holding mutexes or reader/writer locks is discouraged, as the 223caller can sleep for an unbounded amount of time in order to satisfy the 224allocation. 225This can in turn block other threads that wish to acquire locks held by the 226caller. 227It should be noted that 228.Fn kmem_free 229may also block. 230.Pp 231For some locks this is permissible or even unavoidable. 232For others, particularly locks that may be taken from soft interrupt context, 233it is a serious problem. 234As a general rule it is better not to allow this type of situation to develop. 235One way to circumvent the problem is to make allocations speculative and part 236of a retryable sequence. 237For example: 238.Bd -literal 239 retry: 240 /* speculative unlocked check */ 241 if (need to allocate) { 242 new_item = kmem_alloc(sizeof(*new_item), KM_SLEEP); 243 } else { 244 new_item = NULL; 245 } 246 mutex_enter(lock); 247 /* check while holding lock for true status */ 248 if (need to allocate) { 249 if (new_item == NULL) { 250 mutex_exit(lock); 251 goto retry; 252 } 253 consume(new_item); 254 new_item = NULL; 255 } 256 mutex_exit(lock); 257 if (new_item != NULL) { 258 /* did not use it after all */ 259 kmem_free(new_item, sizeof(*new_item)); 260 } 261.Ed 262.\" ------------------------------------------------------------ 263.Sh OPTIONS 264.Ss KMEM_SIZE 265Kernels compiled with the 266.Dv KMEM_SIZE 267option ensure the size given in 268.Fn kmem_free 269matches the actual allocated size. 270On 271.Fn kmem_alloc , 272the kernel will allocate an additional contiguous kmem page of eight 273bytes in the buffer, will register the allocated size in the first kmem 274page of that buffer, and will return a pointer to the second kmem page 275in that same buffer. 276When freeing, the kernel reads the first page, and compares the 277size registered with the one given in 278.Fn kmem_free . 279Any mismatch triggers a panic. 280.Pp 281.Dv KMEM_SIZE 282is enabled by default on 283.Dv DIAGNOSTIC . 284.Sh RETURN VALUES 285On success, 286.Fn kmem_alloc , 287.Fn kmem_asprintf , 288.Fn kmem_intr_alloc , 289.Fn kmem_intr_zalloc , 290.Fn kmem_strdupsize , 291and 292.Fn kmem_zalloc 293return a pointer to allocated memory. 294Otherwise, 295.Dv NULL 296is returned. 297.\" ------------------------------------------------------------ 298.Sh CODE REFERENCES 299The 300.Nm 301subsystem is implemented within the file 302.Pa sys/kern/subr_kmem.c . 303.\" ------------------------------------------------------------ 304.Sh SEE ALSO 305.Xr intro 9 , 306.Xr memoryallocators 9 , 307.Xr percpu 9 , 308.Xr pool_cache 9 , 309.Xr uvm_km 9 310.\" ------------------------------------------------------------ 311.Sh CAVEATS 312The 313.Fn kmem_alloc , 314.Fn kmem_asprintf , 315.Fn kmem_free , 316.Fn kmem_strdupsize , 317.Fn kmem_strfree , 318and 319.Fn kmem_zalloc 320functions cannot be used from interrupt context, from a soft interrupt, 321or from a callout. 322Use 323.Xr pool_cache 9 324in these situations. 325.\" ------------------------------------------------------------ 326.Sh SECURITY CONSIDERATIONS 327As the memory allocated by 328.Fn kmem_alloc 329is uninitialized, it can contain security-sensitive data left by its 330previous user. 331It is the caller's responsibility not to expose it to the world. 332