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