1.\" $OpenBSD: extent.9,v 1.19 2015/11/01 21:26:48 jmc Exp $ 2.\" $NetBSD: extent.9,v 1.15 1999/03/16 00:40:47 garbled Exp $ 3.\" 4.\" Copyright (c) 1996, 1998 The NetBSD Foundation, Inc. 5.\" All rights reserved. 6.\" 7.\" This code is derived from software contributed to The NetBSD Foundation 8.\" by Jason R. Thorpe and Greg Hudson. 9.\" 10.\" Redistribution and use in source and binary forms, with or without 11.\" modification, are permitted provided that the following conditions 12.\" are met: 13.\" 1. Redistributions of source code must retain the above copyright 14.\" notice, this list of conditions and the following disclaimer. 15.\" 2. Redistributions in binary form must reproduce the above copyright 16.\" notice, this list of conditions and the following disclaimer in the 17.\" documentation and/or other materials provided with the distribution. 18.\" 19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29.\" POSSIBILITY OF SUCH DAMAGE. 30.\" 31.Dd $Mdocdate: November 1 2015 $ 32.Dt EXTENT 9 33.Os 34.Sh NAME 35.Nm extent_create , 36.Nm extent_destroy , 37.Nm extent_alloc , 38.Nm extent_alloc_with_descr , 39.Nm extent_alloc_subregion , 40.Nm extent_alloc_subregion_with_descr , 41.Nm extent_alloc_region , 42.Nm extent_free , 43.Nm extent_print 44.Nd general purpose extent manager 45.Sh SYNOPSIS 46.In sys/malloc.h 47.In sys/extent.h 48.Ft struct extent * 49.Fn extent_create "char *name" "u_long start" "u_long end" "int mtype" "caddr_t storage" "size_t storagesize" "int flags" 50.Ft void 51.Fn extent_destroy "struct extent *ex" 52.Ft int 53.Fn extent_alloc "struct extent *ex" "u_long size" "u_long alignment" "u_long skew" "u_long boundary" "int flags" "u_long *result" 54.Ft int 55.Fn extent_alloc_with_descr "struct extent *ex" "u_long size" "u_long alignment" "u_long skew" "u_long boundary" "int flags" "struct extent_region *rp" "u_long *result" 56.Ft int 57.\" too many arguments for a single .Fn 58.Fo extent_alloc_subregion 59.Fa "struct extent *ex" 60.Fa "u_long substart" 61.Fa "u_long subend" 62.Fa "u_long size" 63.Fa "u_long alignment" 64.Fa "u_long skew" 65.Fa "u_long boundary" 66.Fa "int flags" 67.Fa "u_long *result" 68.Fc 69.Ft int 70.\" way too many arguments for a single .Fn 71.Fo extent_alloc_subregion_with_descr 72.Fa "struct extent *ex" 73.Fa "u_long substart" 74.Fa "u_long subend" 75.Fa "u_long size" 76.Fa "u_long alignment" 77.Fa "u_long skew" 78.Fa "u_long boundary" 79.Fa "int flags" 80.Fa "struct extent_region *rp" 81.Fa "u_long *result" 82.Fc 83.Ft int 84.Fn extent_alloc_region "struct extent *ex" "u_long start" "u_long size" "int flags" 85.Ft int 86.Fn extent_free "struct extent *ex" "u_long start" "u_long size" "int flags" 87.Ft void 88.Fn extent_print "struct extent *ex" 89.Sh DESCRIPTION 90The extent manager provides management of areas of memory or 91other enumerable spaces (such as I/O ports). 92An opaque structure called an 93.Nm extent map 94keeps track of allocated regions within the enumerable space. 95.Pp 96.Fn extent_create 97creates an extent map managing the space from 98.Fa start 99to 100.Fa end 101inclusive. 102All memory allocation will use the memory type 103.Fa mtype 104.Po 105see 106.Xr malloc 9 107.Pc . 108The extent map will have the name 109.Fa name , 110used for identification in case of errors or in 111.Xr ddb 4 112.Ic show extents . 113If the flag 114.Dv EX_NOCOALESCE 115is set, internal coalescing of regions is disabled, 116and only entire regions may be freed within the extent map, so that 117.Fn extent_free 118will never have to allocate a region descriptor. 119If the flag 120.Dv EX_FILLED 121is set, the entire space managed by the extent map will be allocated 122upon creation of the extent map, such that selected regions may be 123made available through calls to 124.Fn extent_free . 125.Pp 126Some applications may want to use an extent map but 127can't use 128.Fn malloc 129and 130.Fn free . 131These applications may provide pre-allocated storage for 132all descriptor overhead with the arguments 133.Fa storage 134and 135.Fa storagesize . 136An extent of this type is called a 137.Nm fixed extent . 138If the application can safely use 139.Fn malloc 140and 141.Fn free , 142.Fa storage 143should be 144.Dv NULL . 145A fixed extent has a fixed number of region descriptors, so care 146should be taken to provide enough storage for them; alternatively, the 147flag 148.Dv EX_MALLOCOK 149may be passed to extent requests to indicate that a fixed extent 150map may be extended using a call to 151.Fn malloc . 152Note that passing the flag 153.Dv EX_FILLED 154to 155.Fn extent_create 156will consume a region descriptor upon creation of the extent map. 157.Pp 158The caller should pass the flag 159.Dv EX_WAITOK 160or 161.Dv EX_NOWAIT 162to extent functions that have a memory overhead, to specify whether 163it is okay to wait. 164These functions are 165.Fn extent_create 166(non fixed extents), 167.Fn extent_free 168(unless 169.Dv EX_NOCOALESCE 170is set), 171.Fn extent_alloc , 172.Fn extent_alloc_subregion 173and 174.Fn extent_alloc_region . 175.Pp 176.Fn extent_destroy 177destroys the extent map 178.Fa ex , 179freeing all allocated regions. 180If the extent is not a fixed extent, 181the region and internal extent descriptors themselves are freed. 182This function always succeeds. 183.Pp 184.Fn extent_alloc 185allocates a region in the extent map 186.Fa ex 187of size 188.Fa size 189that fits the provided parameters. 190There are two distinct allocation policies, which are selected by the 191.Fa flags 192argument: 193.Bl -tag -offset indent -width "XXXXXXXXX" 194.It Dv EX_FAST 195Allocate the first region that fits the provided parameters, regardless 196of resulting extent fragmentation. 197.It default 198Allocate the smallest region that is capable of holding the request, 199thus minimizing fragmentation of the extent. 200.El 201.Pp 202The caller may specify that it is okay to wait for space to become free in the 203extent by setting the flag 204.Dv EX_WAITSPACE . 205If 206.Dv EX_WAITSPACE 207is not set, the allocation will fail if the request cannot be 208satisfied without sleeping. 209.Pp 210The request will be aligned to a multiple of 211.Fa alignment . 212That value must be a power of 2. 213If no alignment is necessary, the value 214.Dv EX_NOALIGN 215should be specified. 216If 217.Fa skew 218is non-zero, it modifies the requested alignment result in the following way: 219the value 220.Pq Fa result No - Fa skew 221is aligned to 222.Fa alignment 223boundaries. 224.Fa skew 225must be a smaller number than 226.Fa alignment . 227If 228.Fa boundary 229is not 230.Dv EX_NOBOUNDARY , 231the allocated region will not cross any boundary lines, spaced 232.Fa boundary 233apart. 234If the caller specifies the 235.Dv EX_BOUNDZERO 236flag, boundary lines begin at zero. 237Otherwise, boundary lines begin at the beginning of the extent. 238The allocated region may begin on a 239boundary line, but the end of the region will not touch nor cross a 240boundary line. 241A 242.Fa boundary 243argument smaller than the sum of the requested skew and the size of 244the request is invalid. 245Upon successful completion, 246.Fa *result 247will contain the start of the allocated region. 248.Pp 249.Fn extent_alloc_with_descr 250is similar to 251.Fn extent_alloc 252but allows the caller to provide a pre-allocated region descriptor instead 253of having the function allocate one. 254This function can only be used with extents that have the 255.Dv EX_NOCOALESCE 256property. 257.Pp 258.Fn extent_alloc_subregion 259and 260.Fn extent_alloc_subregion_with_descr 261are generalized versions of 262.Fn extent_alloc 263and 264.Fn extent_alloc_with_descr 265that allow the caller to specify that the allocated region must fall 266within the subregion from 267.Fa substart 268to 269.Fa subend 270inclusive. 271.Pp 272.Fn extent_alloc_region 273allocates the specific region in the extent map 274.Fa ex 275beginning at 276.Fa start 277with the size 278.Fa size . 279If the caller specifies the 280.Dv EX_CONFLICTOK 281flag, the allocation will succeed even if part of the requested region 282has already been allocated. 283The caller may specify that it is okay to wait for the indicated 284region to be free by setting the flag 285.Dv EX_WAITSPACE . 286If neither 287.Dv EX_WAITSPACE 288nor 289.Dv EX_CONFLICTOK 290is set, the allocation will fail if the request cannot be 291satisfied without sleeping. 292.Pp 293.Fn extent_free 294frees a region of 295.Fa size 296bytes starting at 297.Fa start 298in the extent map 299.Fa ex . 300If the extent has the 301.Dv EX_NOCOALESCE 302property, only entire regions may be freed. 303If the extent has the 304.Dv EX_NOCOALESCE 305property and the caller attempts to free a partial region, behavior is 306undefined. 307If called on an extent without the 308.Dv EX_NOCOALESCE 309property, this function can fail with error codes listed below, otherwise 310this function will always succeed. 311.Pp 312.Fn extent_print 313Prints out information about extent 314.Fa ex . 315This function always succeeds. 316.Sh RETURN VALUES 317The behavior of all extent manager functions is undefined if given 318invalid arguments. 319.Fn extent_create 320returns the extent map on success, or 321.Dv NULL 322if it fails to allocate storage for the extent map. 323It always succeeds when creating a fixed extent or when given the flag 324.Dv EX_WAITOK . 325.Fn extent_alloc , 326.Fn extent_alloc_region , 327.Fn extent_alloc_subregion , 328and 329.Fn extent_free 330return one of the following values: 331.Bl -tag -offset indent -width "XXXXXXXX" 332.It Dv 0 333Operation was successful. 334.It Dv ENOMEM 335If 336.Dv EX_NOWAIT 337is specified, the extent manager was not able to allocate a region 338descriptor for the new region or to split a region when freeing a 339partial region. 340.It Dv EAGAIN 341Requested region is not available and 342.Dv EX_WAITSPACE 343was not specified. 344.It Dv EINTR 345Process received a signal while waiting for the requested region to 346become available in the extent. 347.El 348.Sh EXAMPLES 349Here is an example of a (useless) function that uses several of the 350extent manager routines. 351.Bd -literal 352void 353func() 354{ 355 struct extent *foo_ex; 356 u_long region_start; 357 int error; 358 359 /* 360 * Extent "foo" manages a 256k region starting at 0x0 and 361 * only allows complete regions to be freed so that 362 * extent_free() never needs to allocate memory. 363 */ 364 foo_ex = extent_create("foo", 0x0, 0x3ffff, M_DEVBUF, 365 NULL, 0, EX_WAITOK | EX_NOCOALESCE); 366 367 /* 368 * Allocate an 8k region, aligned to a 4k boundary, which 369 * does not cross any of the 3 64k boundaries (at 64k, 370 * 128k, and 192k) within the extent. 371 */ 372 error = extent_alloc(foo_ex, 0x2000, 0x1000, 0x10000, 373 EX_NOWAIT, ®ion_start); 374 if (error) 375 panic("you lose"); 376 377 /* 378 * Give up the extent. 379 */ 380 extent_destroy(foo_ex); 381} 382.Ed 383.\" 384.\" Yeah, right... document EX_CATCH first... 385.\" 386.\" .Sh LIMITATIONS 387.\" The flag 388.\" .Dv EX_CATCH 389.\" cannot be used to catch signals in all circumstances since 390.\" .Xr malloc 9 391.\" does not provide such a functionality. 392.Sh CODE REFERENCES 393The extent manager itself is implemented within the file 394.Pa sys/kern/subr_extent.c . 395.Pp 396The i386 bus management code uses the extent manager for managing I/O 397ports and I/O memory. 398See 399.Pa sys/arch/i386/i386/machdep.c . 400.Sh SEE ALSO 401.Xr ddb 4 , 402.Xr malloc 9 403.Sh HISTORY 404The extent manager appeared in 405.Nx 1.3 . 406.Sh AUTHORS 407.An -nosplit 408The extent manager was designed and implemented by 409.An Jason R. Thorpe Aq Mt thorpej@NetBSD.ORG . 410.An Matthias Drochner Aq Mt drochner@zelux6.zel.kfa-juelich.de 411contributed to the initial testing and optimization of the implementation. 412.An Chris Demetriou Aq Mt cgd@NetBSD.ORG 413contributed many architectural suggestions. 414