Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Oct 2010 22:21:57 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r214037 - projects/ofed/head/sys/ofed/include/linux
Message-ID:  <201010182221.o9IMLvOK087848@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Mon Oct 18 22:21:57 2010
New Revision: 214037
URL: http://svn.freebsd.org/changeset/base/214037

Log:
   - Fill the bitmap for layers that are brought in directly from the
     allocator in idr_get().  Otherwise they will present as empty.
   - Don't forget to set il when traversing the tree in get_new_*
     even when we don't have to allocate a new layer.  This was causing
     large idrs to fail on remove.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas.

Modified:
  projects/ofed/head/sys/ofed/include/linux/linux_idr.c

Modified: projects/ofed/head/sys/ofed/include/linux/linux_idr.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_idr.c	Mon Oct 18 22:19:47 2010	(r214036)
+++ projects/ofed/head/sys/ofed/include/linux/linux_idr.c	Mon Oct 18 22:21:57 2010	(r214037)
@@ -255,6 +255,7 @@ idr_get(struct idr *idr)
 		return (il);
 	}
 	il = malloc(sizeof(*il), M_IDR, M_ZERO | M_NOWAIT);
+	bitmap_fill(&il->bitmap, IDR_SIZE);
 	return (il);
 }
 
@@ -307,10 +308,11 @@ idr_get_new(struct idr *idr, void *ptr, 
 		if (layer == 0)
 			break;
 		if (il->ary[idx] == NULL) {
-			il = il->ary[idx] = idr_get(idr);
-			if (il == NULL)
+			il->ary[idx] = idr_get(idr);
+			if (il->ary[idx] == NULL)
 				goto out;
 		}
+		il = il->ary[idx];
 	}
 	/*
 	 * Allocate the leaf to the consumer.
@@ -328,10 +330,12 @@ idr_get_new(struct idr *idr, void *ptr, 
 	error = 0;
 out:
 	mtx_unlock(&idr->lock);
+#ifdef INVARIANTS
 	if (error == 0 && idr_find(idr, id) != ptr) {
 		panic("idr_get_new: Failed for idr %p, id %d, ptr %p\n",
 		    idr, id, ptr);
 	}
+#endif
 	return (error);
 }
 
@@ -358,6 +362,10 @@ restart:
 		layer++;
 		idx >>= IDR_BITS;
 	}
+	if (layer == MAX_LEVEL + 1) {
+		error = -ENOSPC;
+		goto out;
+	}
 	/*
 	 * Expand the tree until there is free space at or beyond starting_id.
 	 */
@@ -407,10 +415,11 @@ restart:
 		if (layer == 0)
 			break;
 		if (il->ary[idx] == NULL) {
-			il = il->ary[idx] = idr_get(idr);
-			if (il == NULL)
+			il->ary[idx] = idr_get(idr);
+			if (il->ary[idx] == NULL)
 				goto out;
 		}
+		il = il->ary[idx];
 	}
 	/*
 	 * Allocate the leaf to the consumer.
@@ -428,5 +437,11 @@ restart:
 	error = 0;
 out:
 	mtx_unlock(&idr->lock);
+#ifdef INVARIANTS
+	if (error == 0 && idr_find(idr, id) != ptr) {
+		panic("idr_get_new_above: Failed for idr %p, id %d, ptr %p\n",
+		    idr, id, ptr);
+	}
+#endif
 	return (error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010182221.o9IMLvOK087848>