xref: /openbsd/share/man/man9/extent.9 (revision 771fbea0)
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, &region_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