svn commit: r319835 - user/alc/PQ_LAUNDRY/sys/kern
Alan Cox
alc at FreeBSD.org
Sun Jun 11 21:23:46 UTC 2017
Author: alc
Date: Sun Jun 11 21:23:45 2017
New Revision: 319835
URL: https://svnweb.freebsd.org/changeset/base/319835
Log:
Reduce the frequency of hint updates without incurring additional allocation
overhead. Previously, blst_meta_alloc() updated the hint after every
successful allocation. However, these "eager" hint updates are of no actual
benefit if, instead, the "lazy" hint update at the start of
blst_meta_alloc() is generalized to handle all cases where the number of
available blocks is less than the requested allocation. Previously, the
lazy hint update at the start of blst_meta_alloc() only handled the ALL-FULL
case. (I would also note that this change provides consistency between
blist_alloc() and blist_fill() in that their hint maintenance is now
entirely lazy.)
Eliminate unnecessary checks for terminators in blst_meta_alloc() and
blst_meta_fill() when handling ALL-FREE meta nodes.
In blst_meta_alloc(), perform a sanity check on the allocation once rather
than repeating it in a loop.
Add or improve several comments.
Address some nearby style errors.
Modified:
user/alc/PQ_LAUNDRY/sys/kern/subr_blist.c
Modified: user/alc/PQ_LAUNDRY/sys/kern/subr_blist.c
==============================================================================
--- user/alc/PQ_LAUNDRY/sys/kern/subr_blist.c Sun Jun 11 21:13:12 2017 (r319834)
+++ user/alc/PQ_LAUNDRY/sys/kern/subr_blist.c Sun Jun 11 21:23:45 2017 (r319835)
@@ -215,17 +215,19 @@ blist_destroy(blist_t bl)
daddr_t
blist_alloc(blist_t bl, daddr_t count)
{
- daddr_t blk = SWAPBLK_NONE;
+ daddr_t blk;
- if (bl) {
+ if (bl != NULL && count <= bl->bl_root->bm_bighint) {
if (bl->bl_radix == BLIST_BMAP_RADIX)
blk = blst_leaf_alloc(bl->bl_root, 0, count);
else
- blk = blst_meta_alloc(bl->bl_root, 0, count, bl->bl_radix, bl->bl_skip);
+ blk = blst_meta_alloc(bl->bl_root, 0, count,
+ bl->bl_radix, bl->bl_skip);
if (blk != SWAPBLK_NONE)
bl->bl_free -= count;
+ return (blk);
}
- return(blk);
+ return (SWAPBLK_NONE);
}
/*
@@ -417,27 +419,27 @@ blst_meta_alloc(
daddr_t radix,
int skip
) {
+ daddr_t r;
int i;
int next_skip = ((u_int)skip / BLIST_META_RADIX);
- if (scan->u.bmu_avail == 0) {
- /*
- * ALL-ALLOCATED special case
- */
- scan->bm_bighint = 0;
- return(SWAPBLK_NONE);
+ if (scan->u.bmu_avail < count) {
+ scan->bm_bighint = scan->u.bmu_avail;
+ return (SWAPBLK_NONE);
}
+ /*
+ * An ALL-FREE meta node requires special handling before allocating
+ * any of its blocks.
+ */
if (scan->u.bmu_avail == radix) {
radix /= BLIST_META_RADIX;
/*
- * ALL-FREE special case, initialize uninitialize
- * sublevel.
+ * Reinitialize each of the meta node's children. An ALL-FREE
+ * meta node cannot have a terminator in any subtree.
*/
for (i = 1; i <= skip; i += next_skip) {
- if (scan[i].bm_bighint == (daddr_t)-1)
- break;
if (next_skip == 1) {
scan[i].u.bmu_bitmap = (u_daddr_t)-1;
scan[i].bm_bighint = BLIST_BMAP_RADIX;
@@ -450,34 +452,33 @@ blst_meta_alloc(
radix /= BLIST_META_RADIX;
}
+ if (count > radix) {
+ /*
+ * The allocation exceeds the number of blocks that are
+ * managed by a subtree of this meta node.
+ */
+ panic("allocation too large");
+ }
for (i = 1; i <= skip; i += next_skip) {
if (count <= scan[i].bm_bighint) {
/*
- * count fits in object
+ * The allocation might fit in the i'th subtree.
*/
- daddr_t r;
if (next_skip == 1) {
r = blst_leaf_alloc(&scan[i], blk, count);
} else {
- r = blst_meta_alloc(&scan[i], blk, count, radix, next_skip - 1);
+ r = blst_meta_alloc(&scan[i], blk, count,
+ radix, next_skip - 1);
}
if (r != SWAPBLK_NONE) {
scan->u.bmu_avail -= count;
- if (scan->bm_bighint > scan->u.bmu_avail)
- scan->bm_bighint = scan->u.bmu_avail;
- return(r);
+ return (r);
}
} else if (scan[i].bm_bighint == (daddr_t)-1) {
/*
* Terminator
*/
break;
- } else if (count > radix) {
- /*
- * count does not fit in object even if it were
- * complete free.
- */
- panic("blist_meta_alloc: allocation too large");
}
blk += radix;
}
@@ -771,8 +772,13 @@ blst_meta_fill(
int next_skip = ((u_int)skip / BLIST_META_RADIX);
daddr_t nblks = 0;
- if (count > radix)
- panic("blist_meta_fill: allocation too large");
+ if (count > radix) {
+ /*
+ * The allocation exceeds the number of blocks that are
+ * managed by this meta node.
+ */
+ panic("allocation too large");
+ }
if (count == radix || scan->u.bmu_avail == 0) {
/*
* ALL-ALLOCATED special case
@@ -783,15 +789,18 @@ blst_meta_fill(
return nblks;
}
+ /*
+ * An ALL-FREE meta node requires special handling before allocating
+ * any of its blocks.
+ */
if (scan->u.bmu_avail == radix) {
radix /= BLIST_META_RADIX;
/*
- * ALL-FREE special case, initialize sublevel
+ * Reinitialize each of the meta node's children. An ALL-FREE
+ * meta node cannot have a terminator in any subtree.
*/
for (i = 1; i <= skip; i += next_skip) {
- if (scan[i].bm_bighint == (daddr_t)-1)
- break;
if (next_skip == 1) {
scan[i].u.bmu_bitmap = (u_daddr_t)-1;
scan[i].bm_bighint = BLIST_BMAP_RADIX;
More information about the svn-src-user
mailing list