summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/subr_extent.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/sys/kern/subr_extent.c b/sys/kern/subr_extent.c
index 3ac43139310..03c8447f202 100644
--- a/sys/kern/subr_extent.c
+++ b/sys/kern/subr_extent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_extent.c,v 1.20 2002/03/14 01:27:04 millert Exp $ */
+/* $OpenBSD: subr_extent.c,v 1.21 2002/03/21 16:24:16 jason Exp $ */
/* $NetBSD: subr_extent.c,v 1.7 1996/11/21 18:46:34 cgd Exp $ */
/*-
@@ -183,8 +183,8 @@ extent_create(name, start, end, mtype, storage, storagesize, flags)
panic("extent_create: end < start");
}
if (fixed_extent && (storagesize < sizeof(struct extent_fixed)))
- panic("extent_create: fixed extent, bad storagesize 0x%x",
- storagesize);
+ panic("extent_create: fixed extent, bad storagesize 0x%lx",
+ (u_long)storagesize);
if (fixed_extent == 0 && (storagesize != 0 || storage != NULL))
panic("extent_create: storage provided for non-fixed");
#endif
@@ -533,7 +533,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
u_long *result;
{
struct extent_region *rp, *myrp, *last, *bestlast;
- u_long newstart, newend, beststart, bestovh, ovh;
+ u_long newstart, newend, exend, beststart, bestovh, ovh;
u_long dontcross;
int error;
@@ -605,6 +605,12 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
bestlast = NULL;
/*
+ * Keep track of end of free region. This is either the end of extent
+ * or the start of a region past the subend.
+ */
+ exend = ex->ex_end;
+
+ /*
* For N allocated regions, we must make (N + 1)
* checks for unallocated space. The first chunk we
* check is the area from the beginning of the subregion
@@ -645,6 +651,15 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
for (; rp != NULL; rp = rp->er_link.le_next) {
/*
+ * If the region pasts the subend, bail out and see
+ * if we fit against the subend.
+ */
+ if (rp->er_start >= subend) {
+ exend = rp->er_start;
+ break;
+ }
+
+ /*
* Check the chunk before "rp". Note that our
* comparison is safe from overflow conditions.
*/
@@ -661,7 +676,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
* Calculate the next boundary after the start
* of this region.
*/
- dontcross = EXTENT_ALIGN(newstart+1, boundary,
+ dontcross = EXTENT_ALIGN(newstart+1, boundary,
(flags & EX_BOUNDZERO) ? 0 : ex->ex_start)
- 1;
@@ -684,7 +699,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
newend = newstart + (size - 1);
dontcross += boundary;
if (!LE_OV(newstart, size, rp->er_start))
- continue;
+ goto skip;
}
/*
@@ -719,6 +734,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
}
}
+skip:
/*
* Skip past the current region and check again.
*/
@@ -731,14 +747,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
*/
goto fail;
}
-
- /*
- * Check that the current region don't run past the
- * end of the subregion.
- */
- if (!LE_OV(newstart, (size - 1), subend))
- goto fail;
-
+
last = rp;
}
@@ -762,7 +771,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
* Calculate the next boundary after the start
* of this region.
*/
- dontcross = EXTENT_ALIGN(newstart+1, boundary,
+ dontcross = EXTENT_ALIGN(newstart+1, boundary,
(flags & EX_BOUNDZERO) ? 0 : ex->ex_start)
- 1;
@@ -805,7 +814,7 @@ extent_alloc_subregion(ex, substart, subend, size, alignment, skew, boundary,
* fit, or we're taking the first fit, insert
* ourselves into the region list.
*/
- ovh = ex->ex_end - newstart - (size - 1);
+ ovh = exend - newstart - (size - 1);
if ((flags & EX_FAST) || (ovh == 0))
goto found;