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