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