subr_extent.c revision 1.74 1 /* $NetBSD: subr_extent.c,v 1.74 2012/01/27 19:48:40 para Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1998, 2007 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 Matthias Drochner.
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
32 /*
33 * General purpose extent manager.
34 */
35
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: subr_extent.c,v 1.74 2012/01/27 19:48:40 para Exp $");
38
39 #ifdef _KERNEL
40 #include "opt_lockdebug.h"
41
42 #include <sys/param.h>
43 #include <sys/extent.h>
44 #include <sys/kmem.h>
45 #include <sys/pool.h>
46 #include <sys/time.h>
47 #include <sys/systm.h>
48 #include <sys/proc.h>
49
50 #include <uvm/uvm_extern.h>
51
52 #define KMEM_IS_RUNNING (kmem_map != NULL)
53 #elif defined(_EXTENT_TESTING)
54 /*
55 * user-land definitions, so it can fit into a testing harness.
56 */
57 #include <sys/param.h>
58 #include <sys/pool.h>
59 #include <sys/extent.h>
60
61 #include <errno.h>
62 #include <stdlib.h>
63 #include <stdio.h>
64 #include <string.h>
65
66 /*
67 * Use multi-line #defines to avoid screwing up the kernel tags file;
68 * without this, ctags produces a tags file where panic() shows up
69 * in subr_extent.c rather than subr_prf.c.
70 */
71 #define \
72 kmem_alloc(s, flags) malloc(s)
73 #define \
74 kmem_free(p, s) free(p)
75 #define \
76 cv_wait_sig(cv, lock) (EWOULDBLOCK)
77 #define \
78 pool_get(pool, flags) kmem_alloc((pool)->pr_size,0)
79 #define \
80 pool_put(pool, rp) kmem_free(rp,0)
81 #define \
82 panic(a) printf(a)
83 #define mutex_init(a, b, c)
84 #define mutex_destroy(a)
85 #define mutex_enter(l)
86 #define mutex_exit(l)
87 #define cv_wait(cv, lock)
88 #define cv_broadcast(cv)
89 #define cv_init(a, b)
90 #define cv_destroy(a)
91 #define KMEM_IS_RUNNING (1)
92 #define IPL_VM (0)
93 #define MUTEX_DEFAULT (0)
94 #endif
95
96 static struct pool expool;
97
98 /*
99 * Macro to align to an arbitrary power-of-two boundary.
100 */
101 #define EXTENT_ALIGN(_start, _align, _skew) \
102 (((((_start) - (_skew)) + ((_align) - 1)) & (-(_align))) + (_skew))
103
104 /*
105 * Create the extent_region pool.
106 */
107 void
108 extent_init(void)
109 {
110
111 #if defined(_KERNEL)
112 pool_init(&expool, sizeof(struct extent_region), 0, 0, 0,
113 "extent", NULL, IPL_VM);
114 #else
115 expool.pr_size = sizeof(struct extent_region);
116 #endif
117 }
118
119 /*
120 * Allocate an extent region descriptor. EXTENT MUST NOT BE LOCKED.
121 * We will handle any locking we may need.
122 */
123 static struct extent_region *
124 extent_alloc_region_descriptor(struct extent *ex, int flags)
125 {
126 struct extent_region *rp;
127 int exflags, error;
128
129 /*
130 * XXX Make a static, create-time flags word, so we don't
131 * XXX have to lock to read it!
132 */
133 mutex_enter(&ex->ex_lock);
134 exflags = ex->ex_flags;
135 mutex_exit(&ex->ex_lock);
136
137 if (exflags & EXF_FIXED) {
138 struct extent_fixed *fex = (struct extent_fixed *)ex;
139
140 mutex_enter(&ex->ex_lock);
141 for (;;) {
142 if ((rp = LIST_FIRST(&fex->fex_freelist)) != NULL) {
143 /*
144 * Don't muck with flags after pulling it off
145 * the freelist; it may have been dynamically
146 * allocated, and kindly given to us. We
147 * need to remember that information.
148 */
149 LIST_REMOVE(rp, er_link);
150 mutex_exit(&ex->ex_lock);
151 return (rp);
152 }
153 if (flags & EX_MALLOCOK) {
154 mutex_exit(&ex->ex_lock);
155 goto alloc;
156 }
157 if ((flags & EX_WAITOK) == 0) {
158 mutex_exit(&ex->ex_lock);
159 return (NULL);
160 }
161 ex->ex_flags |= EXF_FLWANTED;
162 if ((flags & EX_CATCH) != 0)
163 error = cv_wait_sig(&ex->ex_cv, &ex->ex_lock);
164 else {
165 cv_wait(&ex->ex_cv, &ex->ex_lock);
166 error = 0;
167 }
168 if (error != 0) {
169 mutex_exit(&ex->ex_lock);
170 return (NULL);
171 }
172 }
173 }
174
175 alloc:
176 rp = pool_get(&expool, (flags & EX_WAITOK) ? PR_WAITOK : 0);
177
178 if (rp != NULL)
179 rp->er_flags = ER_ALLOC;
180
181 return (rp);
182 }
183
184 /*
185 * Free an extent region descriptor. EXTENT _MUST_ BE LOCKED!
186 */
187 static void
188 extent_free_region_descriptor(struct extent *ex, struct extent_region *rp)
189 {
190
191 if (ex->ex_flags & EXF_FIXED) {
192 struct extent_fixed *fex = (struct extent_fixed *)ex;
193
194 /*
195 * If someone's waiting for a region descriptor,
196 * be nice and give them this one, rather than
197 * just free'ing it back to the system.
198 */
199 if (rp->er_flags & ER_ALLOC) {
200 if (ex->ex_flags & EXF_FLWANTED) {
201 /* Clear all but ER_ALLOC flag. */
202 rp->er_flags = ER_ALLOC;
203 LIST_INSERT_HEAD(&fex->fex_freelist, rp,
204 er_link);
205 goto wake_em_up;
206 } else
207 pool_put(&expool, rp);
208 } else {
209 /* Clear all flags. */
210 rp->er_flags = 0;
211 LIST_INSERT_HEAD(&fex->fex_freelist, rp, er_link);
212 }
213
214 wake_em_up:
215 ex->ex_flags &= ~EXF_FLWANTED;
216 cv_broadcast(&ex->ex_cv);
217 return;
218 }
219
220 /*
221 * We know it's dynamically allocated if we get here.
222 */
223 pool_put(&expool, rp);
224 }
225
226 /*
227 * Allocate and initialize an extent map.
228 */
229 struct extent *
230 extent_create(const char *name, u_long start, u_long end,
231 void *storage, size_t storagesize, int flags)
232 {
233 struct extent *ex;
234 char *cp = storage;
235 size_t sz = storagesize;
236 struct extent_region *rp;
237 int fixed_extent = (storage != NULL);
238
239 #ifndef _KERNEL
240 extent_init();
241 #endif
242
243 #ifdef DIAGNOSTIC
244 /* Check arguments. */
245 if (name == NULL)
246 panic("extent_create: name == NULL");
247 if (end < start) {
248 printf("extent_create: extent `%s', start 0x%lx, end 0x%lx\n",
249 name, start, end);
250 panic("extent_create: end < start");
251 }
252 if (fixed_extent && (storagesize < sizeof(struct extent_fixed)))
253 panic("extent_create: fixed extent, bad storagesize 0x%lx",
254 (u_long)storagesize);
255 if (fixed_extent == 0 && (storagesize != 0 || storage != NULL))
256 panic("extent_create: storage provided for non-fixed");
257 #endif
258
259 /* Allocate extent descriptor. */
260 if (fixed_extent) {
261 struct extent_fixed *fex;
262
263 memset(storage, 0, storagesize);
264
265 /*
266 * Align all descriptors on "long" boundaries.
267 */
268 fex = (struct extent_fixed *)cp;
269 ex = (struct extent *)fex;
270 cp += ALIGN(sizeof(struct extent_fixed));
271 sz -= ALIGN(sizeof(struct extent_fixed));
272 fex->fex_storage = storage;
273 fex->fex_storagesize = storagesize;
274
275 /*
276 * In a fixed extent, we have to pre-allocate region
277 * descriptors and place them in the extent's freelist.
278 */
279 LIST_INIT(&fex->fex_freelist);
280 while (sz >= ALIGN(sizeof(struct extent_region))) {
281 rp = (struct extent_region *)cp;
282 cp += ALIGN(sizeof(struct extent_region));
283 sz -= ALIGN(sizeof(struct extent_region));
284 LIST_INSERT_HEAD(&fex->fex_freelist, rp, er_link);
285 }
286 } else {
287 ex = (struct extent *)kmem_alloc(sizeof(struct extent),
288 (flags & EX_WAITOK) ? KM_SLEEP : KM_NOSLEEP);
289 if (ex == NULL)
290 return (NULL);
291 }
292
293 /* Fill in the extent descriptor and return it to the caller. */
294 mutex_init(&ex->ex_lock, MUTEX_DEFAULT, IPL_VM);
295 cv_init(&ex->ex_cv, "extent");
296 LIST_INIT(&ex->ex_regions);
297 ex->ex_name = name;
298 ex->ex_start = start;
299 ex->ex_end = end;
300 ex->ex_flags = 0;
301 if (fixed_extent)
302 ex->ex_flags |= EXF_FIXED;
303 if (flags & EX_NOCOALESCE)
304 ex->ex_flags |= EXF_NOCOALESCE;
305 return (ex);
306 }
307
308 /*
309 * Destroy an extent map.
310 * Since we're freeing the data, there can't be any references
311 * so we don't need any locking.
312 */
313 void
314 extent_destroy(struct extent *ex)
315 {
316 struct extent_region *rp, *orp;
317
318 #ifdef DIAGNOSTIC
319 /* Check arguments. */
320 if (ex == NULL)
321 panic("extent_destroy: NULL extent");
322 #endif
323
324 /* Free all region descriptors in extent. */
325 for (rp = LIST_FIRST(&ex->ex_regions); rp != NULL; ) {
326 orp = rp;
327 rp = LIST_NEXT(rp, er_link);
328 LIST_REMOVE(orp, er_link);
329 extent_free_region_descriptor(ex, orp);
330 }
331
332 cv_destroy(&ex->ex_cv);
333 mutex_destroy(&ex->ex_lock);
334
335 /* If we're not a fixed extent, free the extent descriptor itself. */
336 if ((ex->ex_flags & EXF_FIXED) == 0)
337 kmem_free(ex, sizeof(*ex));
338 }
339
340 /*
341 * Insert a region descriptor into the sorted region list after the
342 * entry "after" or at the head of the list (if "after" is NULL).
343 * The region descriptor we insert is passed in "rp". We must
344 * allocate the region descriptor before calling this function!
345 * If we don't need the region descriptor, it will be freed here.
346 */
347 static void
348 extent_insert_and_optimize(struct extent *ex, u_long start, u_long size,
349 int flags, struct extent_region *after, struct extent_region *rp)
350 {
351 struct extent_region *nextr;
352 int appended = 0;
353
354 if (after == NULL) {
355 /*
356 * We're the first in the region list. If there's
357 * a region after us, attempt to coalesce to save
358 * descriptor overhead.
359 */
360 if (((ex->ex_flags & EXF_NOCOALESCE) == 0) &&
361 (LIST_FIRST(&ex->ex_regions) != NULL) &&
362 ((start + size) == LIST_FIRST(&ex->ex_regions)->er_start)) {
363 /*
364 * We can coalesce. Prepend us to the first region.
365 */
366 LIST_FIRST(&ex->ex_regions)->er_start = start;
367 extent_free_region_descriptor(ex, rp);
368 return;
369 }
370
371 /*
372 * Can't coalesce. Fill in the region descriptor
373 * in, and insert us at the head of the region list.
374 */
375 rp->er_start = start;
376 rp->er_end = start + (size - 1);
377 LIST_INSERT_HEAD(&ex->ex_regions, rp, er_link);
378 return;
379 }
380
381 /*
382 * If EXF_NOCOALESCE is set, coalescing is disallowed.
383 */
384 if (ex->ex_flags & EXF_NOCOALESCE)
385 goto cant_coalesce;
386
387 /*
388 * Attempt to coalesce with the region before us.
389 */
390 if ((after->er_end + 1) == start) {
391 /*
392 * We can coalesce. Append ourselves and make
393 * note of it.
394 */
395 after->er_end = start + (size - 1);
396 appended = 1;
397 }
398
399 /*
400 * Attempt to coalesce with the region after us.
401 */
402 if ((LIST_NEXT(after, er_link) != NULL) &&
403 ((start + size) == LIST_NEXT(after, er_link)->er_start)) {
404 /*
405 * We can coalesce. Note that if we appended ourselves
406 * to the previous region, we exactly fit the gap, and
407 * can free the "next" region descriptor.
408 */
409 if (appended) {
410 /*
411 * Yup, we can free it up.
412 */
413 after->er_end = LIST_NEXT(after, er_link)->er_end;
414 nextr = LIST_NEXT(after, er_link);
415 LIST_REMOVE(nextr, er_link);
416 extent_free_region_descriptor(ex, nextr);
417 } else {
418 /*
419 * Nope, just prepend us to the next region.
420 */
421 LIST_NEXT(after, er_link)->er_start = start;
422 }
423
424 extent_free_region_descriptor(ex, rp);
425 return;
426 }
427
428 /*
429 * We weren't able to coalesce with the next region, but
430 * we don't need to allocate a region descriptor if we
431 * appended ourselves to the previous region.
432 */
433 if (appended) {
434 extent_free_region_descriptor(ex, rp);
435 return;
436 }
437
438 cant_coalesce:
439
440 /*
441 * Fill in the region descriptor and insert ourselves
442 * into the region list.
443 */
444 rp->er_start = start;
445 rp->er_end = start + (size - 1);
446 LIST_INSERT_AFTER(after, rp, er_link);
447 }
448
449 /*
450 * Allocate a specific region in an extent map.
451 */
452 int
453 extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
454 {
455 struct extent_region *rp, *last, *myrp;
456 u_long end = start + (size - 1);
457 int error;
458
459 #ifdef DIAGNOSTIC
460 /* Check arguments. */
461 if (ex == NULL)
462 panic("extent_alloc_region: NULL extent");
463 if (size < 1) {
464 printf("extent_alloc_region: extent `%s', size 0x%lx\n",
465 ex->ex_name, size);
466 panic("extent_alloc_region: bad size");
467 }
468 if (end < start) {
469 printf(
470 "extent_alloc_region: extent `%s', start 0x%lx, size 0x%lx\n",
471 ex->ex_name, start, size);
472 panic("extent_alloc_region: overflow");
473 }
474 #endif
475 #ifdef LOCKDEBUG
476 if (flags & EX_WAITSPACE) {
477 ASSERT_SLEEPABLE();
478 }
479 #endif
480
481 /*
482 * Make sure the requested region lies within the
483 * extent.
484 *
485 * We don't lock to check the range, because those values
486 * are never modified, and if another thread deletes the
487 * extent, we're screwed anyway.
488 */
489 if ((start < ex->ex_start) || (end > ex->ex_end)) {
490 #ifdef DIAGNOSTIC
491 printf("extent_alloc_region: extent `%s' (0x%lx - 0x%lx)\n",
492 ex->ex_name, ex->ex_start, ex->ex_end);
493 printf("extent_alloc_region: start 0x%lx, end 0x%lx\n",
494 start, end);
495 panic("extent_alloc_region: region lies outside extent");
496 #else
497 return (EINVAL);
498 #endif
499 }
500
501 /*
502 * Allocate the region descriptor. It will be freed later
503 * if we can coalesce with another region. Don't lock before
504 * here! This could block.
505 */
506 myrp = extent_alloc_region_descriptor(ex, flags);
507 if (myrp == NULL) {
508 #ifdef DIAGNOSTIC
509 printf(
510 "extent_alloc_region: can't allocate region descriptor\n");
511 #endif
512 return (ENOMEM);
513 }
514
515 mutex_enter(&ex->ex_lock);
516 alloc_start:
517
518 /*
519 * Attempt to place ourselves in the desired area of the
520 * extent. We save ourselves some work by keeping the list sorted.
521 * In other words, if the start of the current region is greater
522 * than the end of our region, we don't have to search any further.
523 */
524
525 /*
526 * Keep a pointer to the last region we looked at so
527 * that we don't have to traverse the list again when
528 * we insert ourselves. If "last" is NULL when we
529 * finally insert ourselves, we go at the head of the
530 * list. See extent_insert_and_optimize() for details.
531 */
532 last = NULL;
533
534 LIST_FOREACH(rp, &ex->ex_regions, er_link) {
535 if (rp->er_start > end) {
536 /*
537 * We lie before this region and don't
538 * conflict.
539 */
540 break;
541 }
542
543 /*
544 * The current region begins before we end.
545 * Check for a conflict.
546 */
547 if (rp->er_end >= start) {
548 /*
549 * We conflict. If we can (and want to) wait,
550 * do so.
551 */
552 if (flags & EX_WAITSPACE) {
553 if ((flags & EX_CATCH) != 0)
554 error = cv_wait_sig(&ex->ex_cv,
555 &ex->ex_lock);
556 else {
557 cv_wait(&ex->ex_cv, &ex->ex_lock);
558 error = 0;
559 }
560 if (error == 0)
561 goto alloc_start;
562 mutex_exit(&ex->ex_lock);
563 } else {
564 mutex_exit(&ex->ex_lock);
565 error = EAGAIN;
566 }
567 extent_free_region_descriptor(ex, myrp);
568 return error;
569 }
570 /*
571 * We don't conflict, but this region lies before
572 * us. Keep a pointer to this region, and keep
573 * trying.
574 */
575 last = rp;
576 }
577
578 /*
579 * We don't conflict with any regions. "last" points
580 * to the region we fall after, or is NULL if we belong
581 * at the beginning of the region list. Insert ourselves.
582 */
583 extent_insert_and_optimize(ex, start, size, flags, last, myrp);
584 mutex_exit(&ex->ex_lock);
585 return (0);
586 }
587
588 /*
589 * Macro to check (x + y) <= z. This check is designed to fail
590 * if an overflow occurs.
591 */
592 #define LE_OV(x, y, z) ((((x) + (y)) >= (x)) && (((x) + (y)) <= (z)))
593
594 /*
595 * Allocate a region in an extent map subregion.
596 *
597 * If EX_FAST is specified, we return the first fit in the map.
598 * Otherwise, we try to minimize fragmentation by finding the
599 * smallest gap that will hold the request.
600 *
601 * The allocated region is aligned to "alignment", which must be
602 * a power of 2.
603 */
604 int
605 extent_alloc_subregion1(struct extent *ex, u_long substart, u_long subend,
606 u_long size, u_long alignment, u_long skew, u_long boundary,
607 int flags, u_long *result)
608 {
609 struct extent_region *rp, *myrp, *last, *bestlast;
610 u_long newstart, newend, exend, beststart, bestovh, ovh;
611 u_long dontcross;
612 int error;
613
614 #ifdef DIAGNOSTIC
615 /*
616 * Check arguments.
617 *
618 * We don't lock to check these, because these values
619 * are never modified, and if another thread deletes the
620 * extent, we're screwed anyway.
621 */
622 if (ex == NULL)
623 panic("extent_alloc_subregion: NULL extent");
624 if (result == NULL)
625 panic("extent_alloc_subregion: NULL result pointer");
626 if ((substart < ex->ex_start) || (substart > ex->ex_end) ||
627 (subend > ex->ex_end) || (subend < ex->ex_start)) {
628 printf("extent_alloc_subregion: extent `%s', ex_start 0x%lx, ex_end 0x%lx\n",
629 ex->ex_name, ex->ex_start, ex->ex_end);
630 printf("extent_alloc_subregion: substart 0x%lx, subend 0x%lx\n",
631 substart, subend);
632 panic("extent_alloc_subregion: bad subregion");
633 }
634 if ((size < 1) || ((size - 1) > (subend - substart))) {
635 printf("extent_alloc_subregion: extent `%s', size 0x%lx\n",
636 ex->ex_name, size);
637 panic("extent_alloc_subregion: bad size");
638 }
639 if (alignment == 0)
640 panic("extent_alloc_subregion: bad alignment");
641 if (boundary && (boundary < size)) {
642 printf(
643 "extent_alloc_subregion: extent `%s', size 0x%lx, "
644 "boundary 0x%lx\n", ex->ex_name, size, boundary);
645 panic("extent_alloc_subregion: bad boundary");
646 }
647 #endif
648 #ifdef LOCKDEBUG
649 if (flags & EX_WAITSPACE) {
650 ASSERT_SLEEPABLE();
651 }
652 #endif
653
654 /*
655 * Allocate the region descriptor. It will be freed later
656 * if we can coalesce with another region. Don't lock before
657 * here! This could block.
658 */
659 myrp = extent_alloc_region_descriptor(ex, flags);
660 if (myrp == NULL) {
661 #ifdef DIAGNOSTIC
662 printf(
663 "extent_alloc_subregion: can't allocate region descriptor\n");
664 #endif
665 return (ENOMEM);
666 }
667
668 alloc_start:
669 mutex_enter(&ex->ex_lock);
670
671 /*
672 * Keep a pointer to the last region we looked at so
673 * that we don't have to traverse the list again when
674 * we insert ourselves. If "last" is NULL when we
675 * finally insert ourselves, we go at the head of the
676 * list. See extent_insert_and_optimize() for deatails.
677 */
678 last = NULL;
679
680 /*
681 * Keep track of size and location of the smallest
682 * chunk we fit in.
683 *
684 * Since the extent can be as large as the numeric range
685 * of the CPU (0 - 0xffffffff for 32-bit systems), the
686 * best overhead value can be the maximum unsigned integer.
687 * Thus, we initialize "bestovh" to 0, since we insert ourselves
688 * into the region list immediately on an exact match (which
689 * is the only case where "bestovh" would be set to 0).
690 */
691 bestovh = 0;
692 beststart = 0;
693 bestlast = NULL;
694
695 /*
696 * Keep track of end of free region. This is either the end of extent
697 * or the start of a region past the subend.
698 */
699 exend = ex->ex_end;
700
701 /*
702 * For N allocated regions, we must make (N + 1)
703 * checks for unallocated space. The first chunk we
704 * check is the area from the beginning of the subregion
705 * to the first allocated region after that point.
706 */
707 newstart = EXTENT_ALIGN(substart, alignment, skew);
708 if (newstart < ex->ex_start) {
709 #ifdef DIAGNOSTIC
710 printf(
711 "extent_alloc_subregion: extent `%s' (0x%lx - 0x%lx), alignment 0x%lx\n",
712 ex->ex_name, ex->ex_start, ex->ex_end, alignment);
713 mutex_exit(&ex->ex_lock);
714 panic("extent_alloc_subregion: overflow after alignment");
715 #else
716 extent_free_region_descriptor(ex, myrp);
717 mutex_exit(&ex->ex_lock);
718 return (EINVAL);
719 #endif
720 }
721
722 /*
723 * Find the first allocated region that begins on or after
724 * the subregion start, advancing the "last" pointer along
725 * the way.
726 */
727 LIST_FOREACH(rp, &ex->ex_regions, er_link) {
728 if (rp->er_start >= newstart)
729 break;
730 last = rp;
731 }
732
733 /*
734 * Relocate the start of our candidate region to the end of
735 * the last allocated region (if there was one overlapping
736 * our subrange).
737 */
738 if (last != NULL && last->er_end >= newstart)
739 newstart = EXTENT_ALIGN((last->er_end + 1), alignment, skew);
740
741 for (; rp != NULL; rp = LIST_NEXT(rp, er_link)) {
742 /*
743 * If the region pasts the subend, bail out and see
744 * if we fit against the subend.
745 */
746 if (rp->er_start > subend) {
747 exend = rp->er_start;
748 break;
749 }
750
751 /*
752 * Check the chunk before "rp". Note that our
753 * comparison is safe from overflow conditions.
754 */
755 if (LE_OV(newstart, size, rp->er_start)) {
756 /*
757 * Do a boundary check, if necessary. Note
758 * that a region may *begin* on the boundary,
759 * but it must end before the boundary.
760 */
761 if (boundary) {
762 newend = newstart + (size - 1);
763
764 /*
765 * Calculate the next boundary after the start
766 * of this region.
767 */
768 dontcross = EXTENT_ALIGN(newstart+1, boundary,
769 (flags & EX_BOUNDZERO) ? 0 : ex->ex_start)
770 - 1;
771
772 #if 0
773 printf("newstart=%lx newend=%lx ex_start=%lx ex_end=%lx boundary=%lx dontcross=%lx\n",
774 newstart, newend, ex->ex_start, ex->ex_end,
775 boundary, dontcross);
776 #endif
777
778 /* Check for overflow */
779 if (dontcross < ex->ex_start)
780 dontcross = ex->ex_end;
781 else if (newend > dontcross) {
782 /*
783 * Candidate region crosses boundary.
784 * Throw away the leading part and see
785 * if we still fit.
786 */
787 newstart = dontcross + 1;
788 newend = newstart + (size - 1);
789 dontcross += boundary;
790 if (!LE_OV(newstart, size, rp->er_start))
791 goto skip;
792 }
793
794 /*
795 * If we run past the end of
796 * the extent or the boundary
797 * overflows, then the request
798 * can't fit.
799 */
800 if (newstart + size - 1 > ex->ex_end ||
801 dontcross < newstart)
802 goto fail;
803 }
804
805 /*
806 * We would fit into this space. Calculate
807 * the overhead (wasted space). If we exactly
808 * fit, or we're taking the first fit, insert
809 * ourselves into the region list.
810 */
811 ovh = rp->er_start - newstart - size;
812 if ((flags & EX_FAST) || (ovh == 0))
813 goto found;
814
815 /*
816 * Don't exactly fit, but check to see
817 * if we're better than any current choice.
818 */
819 if ((bestovh == 0) || (ovh < bestovh)) {
820 bestovh = ovh;
821 beststart = newstart;
822 bestlast = last;
823 }
824 }
825
826 skip:
827 /*
828 * Skip past the current region and check again.
829 */
830 newstart = EXTENT_ALIGN((rp->er_end + 1), alignment, skew);
831 if (newstart < rp->er_end) {
832 /*
833 * Overflow condition. Don't error out, since
834 * we might have a chunk of space that we can
835 * use.
836 */
837 goto fail;
838 }
839
840 last = rp;
841 }
842
843 /*
844 * The final check is from the current starting point to the
845 * end of the subregion. If there were no allocated regions,
846 * "newstart" is set to the beginning of the subregion, or
847 * just past the end of the last allocated region, adjusted
848 * for alignment in either case.
849 */
850 if (LE_OV(newstart, (size - 1), subend)) {
851 /*
852 * Do a boundary check, if necessary. Note
853 * that a region may *begin* on the boundary,
854 * but it must end before the boundary.
855 */
856 if (boundary) {
857 newend = newstart + (size - 1);
858
859 /*
860 * Calculate the next boundary after the start
861 * of this region.
862 */
863 dontcross = EXTENT_ALIGN(newstart+1, boundary,
864 (flags & EX_BOUNDZERO) ? 0 : ex->ex_start)
865 - 1;
866
867 #if 0
868 printf("newstart=%lx newend=%lx ex_start=%lx ex_end=%lx boundary=%lx dontcross=%lx\n",
869 newstart, newend, ex->ex_start, ex->ex_end,
870 boundary, dontcross);
871 #endif
872
873 /* Check for overflow */
874 if (dontcross < ex->ex_start)
875 dontcross = ex->ex_end;
876 else if (newend > dontcross) {
877 /*
878 * Candidate region crosses boundary.
879 * Throw away the leading part and see
880 * if we still fit.
881 */
882 newstart = dontcross + 1;
883 newend = newstart + (size - 1);
884 dontcross += boundary;
885 if (!LE_OV(newstart, (size - 1), subend))
886 goto fail;
887 }
888
889 /*
890 * If we run past the end of
891 * the extent or the boundary
892 * overflows, then the request
893 * can't fit.
894 */
895 if (newstart + size - 1 > ex->ex_end ||
896 dontcross < newstart)
897 goto fail;
898 }
899
900 /*
901 * We would fit into this space. Calculate
902 * the overhead (wasted space). If we exactly
903 * fit, or we're taking the first fit, insert
904 * ourselves into the region list.
905 */
906 ovh = exend - newstart - (size - 1);
907 if ((flags & EX_FAST) || (ovh == 0))
908 goto found;
909
910 /*
911 * Don't exactly fit, but check to see
912 * if we're better than any current choice.
913 */
914 if ((bestovh == 0) || (ovh < bestovh)) {
915 bestovh = ovh;
916 beststart = newstart;
917 bestlast = last;
918 }
919 }
920
921 fail:
922 /*
923 * One of the following two conditions have
924 * occurred:
925 *
926 * There is no chunk large enough to hold the request.
927 *
928 * If EX_FAST was not specified, there is not an
929 * exact match for the request.
930 *
931 * Note that if we reach this point and EX_FAST is
932 * set, then we know there is no space in the extent for
933 * the request.
934 */
935 if (((flags & EX_FAST) == 0) && (bestovh != 0)) {
936 /*
937 * We have a match that's "good enough".
938 */
939 newstart = beststart;
940 last = bestlast;
941 goto found;
942 }
943
944 /*
945 * No space currently available. Wait for it to free up,
946 * if possible.
947 */
948 if (flags & EX_WAITSPACE) {
949 if ((flags & EX_CATCH) != 0) {
950 error = cv_wait_sig(&ex->ex_cv, &ex->ex_lock);
951 } else {
952 cv_wait(&ex->ex_cv, &ex->ex_lock);
953 error = 0;
954 }
955 if (error == 0)
956 goto alloc_start;
957 mutex_exit(&ex->ex_lock);
958 } else {
959 mutex_exit(&ex->ex_lock);
960 error = EAGAIN;
961 }
962
963 extent_free_region_descriptor(ex, myrp);
964 return error;
965
966 found:
967 /*
968 * Insert ourselves into the region list.
969 */
970 extent_insert_and_optimize(ex, newstart, size, flags, last, myrp);
971 mutex_exit(&ex->ex_lock);
972 *result = newstart;
973 return (0);
974 }
975
976 int
977 extent_alloc_subregion(struct extent *ex, u_long start, u_long end, u_long size,
978 u_long alignment, u_long boundary, int flags, u_long *result)
979 {
980
981 return (extent_alloc_subregion1(ex, start, end, size, alignment,
982 0, boundary, flags, result));
983 }
984
985 int
986 extent_alloc(struct extent *ex, u_long size, u_long alignment, u_long boundary,
987 int flags, u_long *result)
988 {
989
990 return (extent_alloc_subregion1(ex, ex->ex_start, ex->ex_end,
991 size, alignment, 0, boundary,
992 flags, result));
993 }
994
995 int
996 extent_alloc1(struct extent *ex, u_long size, u_long alignment, u_long skew,
997 u_long boundary, int flags, u_long *result)
998 {
999
1000 return (extent_alloc_subregion1(ex, ex->ex_start, ex->ex_end,
1001 size, alignment, skew, boundary,
1002 flags, result));
1003 }
1004
1005 int
1006 extent_free(struct extent *ex, u_long start, u_long size, int flags)
1007 {
1008 struct extent_region *rp, *nrp = NULL;
1009 u_long end = start + (size - 1);
1010 int coalesce;
1011
1012 #ifdef DIAGNOSTIC
1013 /*
1014 * Check arguments.
1015 *
1016 * We don't lock to check these, because these values
1017 * are never modified, and if another thread deletes the
1018 * extent, we're screwed anyway.
1019 */
1020 if (ex == NULL)
1021 panic("extent_free: NULL extent");
1022 if ((start < ex->ex_start) || (end > ex->ex_end)) {
1023 extent_print(ex);
1024 printf("extent_free: extent `%s', start 0x%lx, size 0x%lx\n",
1025 ex->ex_name, start, size);
1026 panic("extent_free: extent `%s', region not within extent",
1027 ex->ex_name);
1028 }
1029 /* Check for an overflow. */
1030 if (end < start) {
1031 extent_print(ex);
1032 printf("extent_free: extent `%s', start 0x%lx, size 0x%lx\n",
1033 ex->ex_name, start, size);
1034 panic("extent_free: overflow");
1035 }
1036 #endif
1037
1038 /*
1039 * If we're allowing coalescing, we must allocate a region
1040 * descriptor now, since it might block.
1041 *
1042 * XXX Make a static, create-time flags word, so we don't
1043 * XXX have to lock to read it!
1044 */
1045 mutex_enter(&ex->ex_lock);
1046 coalesce = (ex->ex_flags & EXF_NOCOALESCE) == 0;
1047 mutex_exit(&ex->ex_lock);
1048
1049 if (coalesce) {
1050 /* Allocate a region descriptor. */
1051 nrp = extent_alloc_region_descriptor(ex, flags);
1052 if (nrp == NULL)
1053 return (ENOMEM);
1054 }
1055
1056 mutex_enter(&ex->ex_lock);
1057
1058 /*
1059 * Find region and deallocate. Several possibilities:
1060 *
1061 * 1. (start == er_start) && (end == er_end):
1062 * Free descriptor.
1063 *
1064 * 2. (start == er_start) && (end < er_end):
1065 * Adjust er_start.
1066 *
1067 * 3. (start > er_start) && (end == er_end):
1068 * Adjust er_end.
1069 *
1070 * 4. (start > er_start) && (end < er_end):
1071 * Fragment region. Requires descriptor alloc.
1072 *
1073 * Cases 2, 3, and 4 require that the EXF_NOCOALESCE flag
1074 * is not set.
1075 */
1076 LIST_FOREACH(rp, &ex->ex_regions, er_link) {
1077 /*
1078 * Save ourselves some comparisons; does the current
1079 * region end before chunk to be freed begins? If so,
1080 * then we haven't found the appropriate region descriptor.
1081 */
1082 if (rp->er_end < start)
1083 continue;
1084
1085 /*
1086 * Save ourselves some traversal; does the current
1087 * region begin after the chunk to be freed ends? If so,
1088 * then we've already passed any possible region descriptors
1089 * that might have contained the chunk to be freed.
1090 */
1091 if (rp->er_start > end)
1092 break;
1093
1094 /* Case 1. */
1095 if ((start == rp->er_start) && (end == rp->er_end)) {
1096 LIST_REMOVE(rp, er_link);
1097 extent_free_region_descriptor(ex, rp);
1098 goto done;
1099 }
1100
1101 /*
1102 * The following cases all require that EXF_NOCOALESCE
1103 * is not set.
1104 */
1105 if (!coalesce)
1106 continue;
1107
1108 /* Case 2. */
1109 if ((start == rp->er_start) && (end < rp->er_end)) {
1110 rp->er_start = (end + 1);
1111 goto done;
1112 }
1113
1114 /* Case 3. */
1115 if ((start > rp->er_start) && (end == rp->er_end)) {
1116 rp->er_end = (start - 1);
1117 goto done;
1118 }
1119
1120 /* Case 4. */
1121 if ((start > rp->er_start) && (end < rp->er_end)) {
1122 /* Fill in new descriptor. */
1123 nrp->er_start = end + 1;
1124 nrp->er_end = rp->er_end;
1125
1126 /* Adjust current descriptor. */
1127 rp->er_end = start - 1;
1128
1129 /* Insert new descriptor after current. */
1130 LIST_INSERT_AFTER(rp, nrp, er_link);
1131
1132 /* We used the new descriptor, so don't free it below */
1133 nrp = NULL;
1134 goto done;
1135 }
1136 }
1137
1138 /* Region not found, or request otherwise invalid. */
1139 mutex_exit(&ex->ex_lock);
1140 extent_print(ex);
1141 printf("extent_free: start 0x%lx, end 0x%lx\n", start, end);
1142 panic("extent_free: region not found");
1143
1144 done:
1145 if (nrp != NULL)
1146 extent_free_region_descriptor(ex, nrp);
1147 cv_broadcast(&ex->ex_cv);
1148 mutex_exit(&ex->ex_lock);
1149 return (0);
1150 }
1151
1152 void
1153 extent_print(struct extent *ex)
1154 {
1155 struct extent_region *rp;
1156
1157 if (ex == NULL)
1158 panic("extent_print: NULL extent");
1159
1160 mutex_enter(&ex->ex_lock);
1161
1162 printf("extent `%s' (0x%lx - 0x%lx), flags = 0x%x\n", ex->ex_name,
1163 ex->ex_start, ex->ex_end, ex->ex_flags);
1164
1165 LIST_FOREACH(rp, &ex->ex_regions, er_link)
1166 printf(" 0x%lx - 0x%lx\n", rp->er_start, rp->er_end);
1167
1168 mutex_exit(&ex->ex_lock);
1169 }
1170