svn commit: r320417 - head/sys/kern

Alan Cox alc at FreeBSD.org
Tue Jun 27 17:45:28 UTC 2017


Author: alc
Date: Tue Jun 27 17:45:26 2017
New Revision: 320417
URL: https://svnweb.freebsd.org/changeset/base/320417

Log:
  Address the remaining integer overflow issues with the "skip" parameters
  and "next_skip" variables.  The "skip" value in struct blist has long been
  a 64-bit quantity but various functions have implicitly truncated this
  value to 32 bits.  Now, all arithmetic involving the "skip" value is 64
  bits wide.  (This should allow us to relax the size limit on a swap device
  in the swap pager.)
  
  Maintain the ability to test this allocator as a user-space application by
  including <stdbool.h>.
  
  Remove an unused variable from blst_radix_print().
  
  Reviewed by:	kib, markj
  MFC after:	4 weeks
  Differential Revision:	https://reviews.freebsd.org/D11358

Modified:
  head/sys/kern/subr_blist.c

Modified: head/sys/kern/subr_blist.c
==============================================================================
--- head/sys/kern/subr_blist.c	Tue Jun 27 17:43:28 2017	(r320416)
+++ head/sys/kern/subr_blist.c	Tue Jun 27 17:45:26 2017	(r320417)
@@ -105,6 +105,7 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdbool.h>
 
 #define	bitcount64(x)	__bitcount64((uint64_t)(x))
 #define malloc(a,b,c)	calloc(a, 1)
@@ -125,17 +126,17 @@ static daddr_t	blst_meta_alloc(blmeta_t *scan, daddr_t
 		    daddr_t radix, daddr_t skip, daddr_t cursor);
 static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count);
 static void blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, 
-					daddr_t radix, int skip, daddr_t blk);
+		    daddr_t radix, daddr_t skip, daddr_t blk);
 static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, 
 				daddr_t skip, blist_t dest, daddr_t count);
 static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count);
 static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count,
-				daddr_t radix, int skip, daddr_t blk);
-static daddr_t	blst_radix_init(blmeta_t *scan, daddr_t radix, 
-						int skip, daddr_t count);
+		    daddr_t radix, daddr_t skip, daddr_t blk);
+static daddr_t	blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip,
+		    daddr_t count);
 #ifndef _KERNEL
-static void	blst_radix_print(blmeta_t *scan, daddr_t blk, 
-					daddr_t radix, int skip, int tab);
+static void	blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix,
+		    daddr_t skip, int tab);
 #endif
 
 #ifdef _KERNEL
@@ -157,18 +158,18 @@ blist_t 
 blist_create(daddr_t blocks, int flags)
 {
 	blist_t bl;
-	daddr_t nodes, radix;
-	int skip = 0;
+	daddr_t nodes, radix, skip;
 
 	/*
 	 * Calculate radix and skip field used for scanning.
 	 */
 	radix = BLIST_BMAP_RADIX;
-
+	skip = 0;
 	while (radix < blocks) {
 		radix *= BLIST_META_RADIX;
 		skip = (skip + 1) * BLIST_META_RADIX;
 	}
+	nodes = 1 + blst_radix_init(NULL, radix, skip, blocks);
 
 	bl = malloc(sizeof(struct blist), M_SWAP, flags);
 	if (bl == NULL)
@@ -178,13 +179,12 @@ blist_create(daddr_t blocks, int flags)
 	bl->bl_radix = radix;
 	bl->bl_skip = skip;
 	bl->bl_cursor = 0;
-	nodes = 1 + blst_radix_init(NULL, radix, bl->bl_skip, blocks);
 	bl->bl_root = malloc(nodes * sizeof(blmeta_t), M_SWAP, flags);
 	if (bl->bl_root == NULL) {
 		free(bl, M_SWAP);
 		return (NULL);
 	}
-	blst_radix_init(bl->bl_root, radix, bl->bl_skip, blocks);
+	blst_radix_init(bl->bl_root, radix, skip, blocks);
 
 #if defined(BLIST_DEBUG)
 	printf(
@@ -569,16 +569,11 @@ blst_leaf_free(
  */
 
 static void 
-blst_meta_free(
-	blmeta_t *scan, 
-	daddr_t freeBlk,
-	daddr_t count,
-	daddr_t radix, 
-	int skip,
-	daddr_t blk
-) {
-	int i;
-	int next_skip = ((u_int)skip / BLIST_META_RADIX);
+blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
+    daddr_t skip, daddr_t blk)
+{
+	daddr_t i, next_skip, v;
+	int child;
 
 #if 0
 	printf("free (%llx,%lld) FROM (%llx,%lld)\n",
@@ -586,6 +581,7 @@ blst_meta_free(
 	    (long long)blk, (long long)radix
 	);
 #endif
+	next_skip = skip / BLIST_META_RADIX;
 
 	if (scan->u.bmu_avail == 0) {
 		/*
@@ -630,13 +626,10 @@ blst_meta_free(
 
 	radix /= BLIST_META_RADIX;
 
-	i = (freeBlk - blk) / radix;
-	blk += i * radix;
-	i = i * next_skip + 1;
-
+	child = (freeBlk - blk) / radix;
+	blk += child * radix;
+	i = 1 + child * next_skip;
 	while (i <= skip && blk < freeBlk + count) {
-		daddr_t v;
-
 		v = blk + radix - freeBlk;
 		if (v > count)
 			v = count;
@@ -673,8 +666,7 @@ static void blst_copy(
 	blist_t dest,
 	daddr_t count
 ) {
-	int next_skip;
-	int i;
+	daddr_t i, next_skip;
 
 	/*
 	 * Leaf node
@@ -719,7 +711,7 @@ static void blst_copy(
 
 
 	radix /= BLIST_META_RADIX;
-	next_skip = ((u_int)skip / BLIST_META_RADIX);
+	next_skip = skip / BLIST_META_RADIX;
 
 	for (i = 1; count && i <= skip; i += next_skip) {
 		if (scan[i].bm_bighint == (daddr_t)-1)
@@ -786,17 +778,11 @@ blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count)
  *	number of blocks allocated by the call.
  */
 static daddr_t
-blst_meta_fill(
-	blmeta_t *scan,
-	daddr_t allocBlk,
-	daddr_t count,
-	daddr_t radix, 
-	int skip,
-	daddr_t blk
-) {
-	int i;
-	int next_skip = ((u_int)skip / BLIST_META_RADIX);
-	daddr_t nblks = 0;
+blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
+    daddr_t skip, daddr_t blk)
+{
+	daddr_t i, nblks, next_skip, v;
+	int child;
 
 	if (count > radix) {
 		/*
@@ -814,6 +800,7 @@ blst_meta_fill(
 		scan->bm_bighint = 0;
 		return nblks;
 	}
+	next_skip = skip / BLIST_META_RADIX;
 
 	/*
 	 * An ALL-FREE meta node requires special handling before allocating
@@ -839,13 +826,11 @@ blst_meta_fill(
 		radix /= BLIST_META_RADIX;
 	}
 
-	i = (allocBlk - blk) / radix;
-	blk += i * radix;
-	i = i * next_skip + 1;
-
+	nblks = 0;
+	child = (allocBlk - blk) / radix;
+	blk += child * radix;
+	i = 1 + child * next_skip;
 	while (i <= skip && blk < allocBlk + count) {
-		daddr_t v;
-
 		v = blk + radix - allocBlk;
 		if (v > count)
 			v = count;
@@ -878,12 +863,12 @@ blst_meta_fill(
  */
 
 static daddr_t	
-blst_radix_init(blmeta_t *scan, daddr_t radix, int skip, daddr_t count)
+blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip, daddr_t count)
 {
-	int i;
-	int next_skip;
-	daddr_t memindex = 0;
+	daddr_t i, memindex, next_skip;
 
+	memindex = 0;
+
 	/*
 	 * Leaf node
 	 */
@@ -908,7 +893,7 @@ blst_radix_init(blmeta_t *scan, daddr_t radix, int ski
 	}
 
 	radix /= BLIST_META_RADIX;
-	next_skip = ((u_int)skip / BLIST_META_RADIX);
+	next_skip = skip / BLIST_META_RADIX;
 
 	for (i = 1; i <= skip; i += next_skip) {
 		if (count >= radix) {
@@ -950,11 +935,10 @@ blst_radix_init(blmeta_t *scan, daddr_t radix, int ski
 #ifdef BLIST_DEBUG
 
 static void	
-blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, int skip, int tab)
+blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
+    int tab)
 {
-	int i;
-	int next_skip;
-	int lastState = 0;
+	daddr_t i, next_skip;
 
 	if (radix == BLIST_BMAP_RADIX) {
 		printf(
@@ -996,7 +980,7 @@ blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t 
 	);
 
 	radix /= BLIST_META_RADIX;
-	next_skip = ((u_int)skip / BLIST_META_RADIX);
+	next_skip = skip / BLIST_META_RADIX;
 	tab += 4;
 
 	for (i = 1; i <= skip; i += next_skip) {
@@ -1006,7 +990,6 @@ blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t 
 			    tab, tab, "",
 			    (long long)blk, (long long)radix
 			);
-			lastState = 0;
 			break;
 		}
 		blst_radix_print(


More information about the svn-src-all mailing list