Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Mar 2011 20:49:54 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 190437 for review
Message-ID:  <201103232049.p2NKnsQE031101@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@190437?ac=10

Change 190437 by jhb@jhb_jhbbsd on 2011/03/23 20:49:39

	Additional tests to cover growing to the end of a region and
	then shrinking back as well as ensuring we fail with EBUSY if
	we try to grow into an already-allocated resource.

Affected files ...

.. //depot/projects/pci/sys/modules/rman/rman.c#4 edit

Differences ...

==== //depot/projects/pci/sys/modules/rman/rman.c#4 (text+ko) ====

@@ -9,8 +9,11 @@
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 
+#define	REGION_START	0x100
+#define	REGION_END	0x200
+
 struct rman test;
-struct resource *r;
+struct resource *r, *s;
 
 /* XXX: Gross hack so we can do assertions.  Copied from subr_rman.c. */
 struct resource_i {
@@ -109,45 +112,41 @@
 assert_rman_ok(void)
 {
 	struct resource_i *i;
+	enum { UNKNOWN, FREE, BUSY } prev, state;
+	int seen_r, seen_s;
 
+	seen_r = 0;
+	seen_s = 0;
 	i = TAILQ_FIRST(&test.rm_list);
 	KASSERT(i != NULL, ("empty rman"));
-	KASSERT(i->r_start == 0, ("first entry does not start at 0"));
-	if (r == NULL) {
-		/* There should be one free entry for the entire region. */
-		KASSERT(i->r_flags == 0 && i->r_end == 100, ("bad entry"));
-		return;
-	}
+	KASSERT(i->r_start == REGION_START, ("first entry has bad start"));
+	prev = UNKNOWN;
 
-	/*
-	 * If r does not start at 0, then there should be one free entry
-	 * before r.
-	 */
-	if (rman_get_start(r) != 0) {
-		KASSERT(i->r_flags == 0 && i->r_end + 1 == rman_get_start(r),
-		    ("bogus first free entry"));
-		i = TAILQ_NEXT(i, r_link);
-	}
+	while (i != NULL) {
+		state = i->r_flags == 0 ? FREE : BUSY;
+		KASSERT(i->r_start >= REGION_START && i->r_end <= REGION_END,
+		    ("bad range"));
+		KASSERT(state != FREE || prev != FREE,
+		    ("adjacent free regions"));
+		if (TAILQ_NEXT(i, r_link) != NULL)
+			KASSERT(i->r_end + 1 == TAILQ_NEXT(i->r_link)->r_start,
+			    ("entries not adjacent"));
+		else
+			KASSERT(i->r_end == REGION_END, ("bad last entry"));
 
-	/*
-	 * 'i' should now be the entry holding allocated resource 'r'
-	 */
-	KASSERT(r == &i->r_r, ("resource mismatch"));
-	KASSERT(i->r_flags & RF_ALLOCATED, ("r not allocated"));
-
-	/*
-	 * If r does not end at 100, then there should be one free entry
-	 * after r.
-	 */
-	if (i->r_end != 100) {
+		if (state == BUSY) {
+			if (r == &i->r_r)
+				seen_r++;
+			else if (s == &i->r_r)
+				seen_s++;
+			KASSERT(i->r_flags & RF_ALLOCATED,
+			    ("busy entry not allocated"));
+		}
 		i = TAILQ_NEXT(i, r_link);
-		KASSERT(i->r_flags == 0 && rman_get_end(r) + 1 == i->r_start,
-		    ("bogus last free entry"));
 	}
 
-	/* 'i' should now reference the last entry ending at 100. */
-	KASSERT(i->r_end == 100 && TAILQ_NEXT(i, r_link) == NULL,
-	    ("bad last entry"));
+	KASSERT(r == NULL || seen_r == 1, ("r mismatch"));
+	KASSERT(s == NULL || seen_s == 1, ("s mismatch"));
 }
 
 static void
@@ -158,14 +157,14 @@
 #define ADJUST_SHOULD_FAIL(start, end, err) do {			\
 	error = rman_adjust_resource(r, (start), (end));		\
 	if (error == (err))						\
-		printf("Correctly failed to adjust to (%u, %u)\n",	\
+		printf("Correctly failed to adjust to (%x, %x)\n",	\
 		    (start), (end));					\
 	else {								\
 		if (error)						\
-			printf("Failed to adjust to (%u, %u) with %d\n", \
+			printf("Failed to adjust to (%x, %x) with %d\n", \
 			    (start), (end), error);			\
 		else							\
-			printf("Incorrectly adjusted to (%lu, %lu)\n",	\
+			printf("Incorrectly adjusted to (%lx, %lx)\n",	\
 			    rman_get_start(r), rman_get_end(r));	\
 		return;							\
 	}								\
@@ -175,61 +174,122 @@
 #define ADJUST_SHOULD_WORK(start, end) do {				\
 	error = rman_adjust_resource(r, (start), (end));		\
 	if (error) {							\
-		printf("Failed to adjust to (%u, %u) with %d\n",	\
+		printf("Failed to adjust to (%x, %x) with %d\n",	\
 		    (start), (end), error);				\
 		return;							\
 	}								\
 	if (rman_get_start(r) != (start) || rman_get_end(r) != (end)) {	\
-		printf("Adjusted incorrectly, tried (%u, %u),"		\
-		    " got (%lu, %lu)\n", (start), (end),		\
+		printf("Adjusted incorrectly, tried (%x, %x),"		\
+		    " got (%lx, %lx)\n", (start), (end),		\
 		    rman_get_start(r), rman_get_end(r));		\
 		return;							\
 	}								\
-	printf("Adjusted to (%lu, %lu)\n", rman_get_start(r),		\
+	printf("Adjusted to (%lx, %lx)\n", rman_get_start(r),		\
 	    rman_get_end(r));						\
 	assert_rman_ok();						\
 } while (0)
 
-	/* Allocate a range in the middle: 30-60. */
+	/* Allocate a range in the middle: 0x130-0x160. */
 	if (r != NULL)
 		rman_release_resource(r);
-	r = rman_reserve_resource(&test, 30, 60, 30, 0, NULL);
+	if (s != NULL) {
+		rman_release_resource(s);
+		s = NULL;
+	}
+	r = rman_reserve_resource(&test, 0x130, 0x160, 0x30, 0, NULL);
 	if (r == NULL) {
 		printf("Failed to allocate resource\n");
 		return;
 	}
-	printf("Allocated (%lu, %lu)\n", rman_get_start(r), rman_get_end(r));
+	printf("Allocated (%lx, %lx)\n", rman_get_start(r), rman_get_end(r));
 	assert_rman_ok();
 
 	/* Non-overlapping adjust regions should fail. */
-	ADJUST_SHOULD_FAIL(5, 10, EINVAL);
-	ADJUST_SHOULD_FAIL(5, 29, EINVAL);
-	ADJUST_SHOULD_FAIL(65, 70, EINVAL);
-	ADJUST_SHOULD_FAIL(61, 70, EINVAL);
+	ADJUST_SHOULD_FAIL(0x105, 0x110, EINVAL);
+	ADJUST_SHOULD_FAIL(0x105, 0x12f, EINVAL);
+	ADJUST_SHOULD_FAIL(0x165, 0x170, EINVAL);
+	ADJUST_SHOULD_FAIL(0x161, 0x170, EINVAL);
 
 	/* Shrinking just one end should work. */
-	ADJUST_SHOULD_WORK(35, 60);
-	ADJUST_SHOULD_WORK(35, 55);
+	ADJUST_SHOULD_WORK(0x135, 0x160);
+	ADJUST_SHOULD_WORK(0x135, 0x155);
 
 	/* Expanding either end should work. */
-	ADJUST_SHOULD_WORK(30, 55);
-	ADJUST_SHOULD_WORK(30, 60);
+	ADJUST_SHOULD_WORK(0x130, 0x155);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
 
 	/* Shrinking both ends. */
-	ADJUST_SHOULD_WORK(35, 55);
+	ADJUST_SHOULD_WORK(0x135, 0x155);
 
 	/* Expanding both ends. */
-	ADJUST_SHOULD_WORK(30, 60);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
 
 	/* Shrinking one end, expanding the other. */
-	ADJUST_SHOULD_WORK(35, 65);
-	ADJUST_SHOULD_WORK(30, 60);
+	ADJUST_SHOULD_WORK(0x135, 0x165);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
 
 	/* Only overlapping with old region at one end. */
-	ADJUST_SHOULD_WORK(60, 75);
-	ADJUST_SHOULD_WORK(30, 60);
+	ADJUST_SHOULD_WORK(0x160, 0x175);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
+
+	/* Expanding to the edges and then shrinking. */
+	ADJUST_SHOULD_WORK(REGION_START, REGION_END);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
+
+	/* Attempting to adjust to a region outside of the rman should fail. */
+	ADJUST_SHOULD_FAIL(REGION_START / 2, 0x160, EBUSY);
+	ADJUST_SHOULD_FAIL(0x130, REGION_END + 0x100, EBUSY);
+
+	/* Allocate a second resource at 0x161 - 0x180. */
+	s = rman_reserve_resource(&test, 0x161, 0x180, 0x20, 0, NULL);
+	if (s == NULL) {
+		printf("Failed to allocate second resource\n");
+		return;
+	}
+	printf("Allocated (%lx, %lx)\n", rman_get_start(s), rman_get_end(s));
+	assert_rman_ok();
+
+	/* Trying to expand into 's' should fail. */
+	ADJUST_SHOULD_FAIL(0x130, 0x161, EBUSY);
+	ADJUST_SHOULD_FAIL(0x130, 0x170, EBUSY);
+
+	/* Shrink down to leave some room. */
+	ADJUST_SHOULD_WORK(0x130, 0x150);
+
+	/* Trying to expand into 's' should fail. */
+	ADJUST_SHOULD_FAIL(0x130, 0x170, EBUSY);
+
+	/* Should be able to expand back up to 's'. */
+	ADJUST_SHOULD_WORK(0x130, 0x158);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
+
+	/* Move 's' down below 'r'. */
+	rman_release_resource(s);
+	s = rman_reserve_resource(&test, 0x120, 0x12f, 0x10, 0, NULL);
+	if (s == NULL) {
+		printf("Failed to allocate third resource\n");
+		return;
+	}
+	printf("Allocated (%lx, %lx)\n", rman_get_start(s), rman_get_end(s));
+	assert_rman_ok();
+
+	/* Trying to expand into 's' should fail. */
+	ADJUST_SHOULD_FAIL(0x12f, 0x160, EBUSY);
+	ADJUST_SHOULD_FAIL(0x128, 0x160, EBUSY);
+
+	/* Shrink up to leave some room. */
+	ADJUST_SHOULD_WORK(0x140, 0x160);
+
+	/* Trying to expand into 's' should fail. */
+	ADJUST_SHOULD_FAIL(0x128, 0x160, EBUSY);
+
+	/* Should be able to expand back down to 's'. */
+	ADJUST_SHOULD_WORK(0x138, 0x160);
+	ADJUST_SHOULD_WORK(0x130, 0x160);
 
 	/* Cleaning up. */
+	rman_release_resource(s);
+	s = NULL;
 	rman_release_resource(r);
 	r = NULL;
 	assert_rman_ok();
@@ -255,16 +315,16 @@
 {
 	int error;
 
-	test.rm_start = 0;
+	test.rm_start = REGION_START;
 	test.rm_type = RMAN_ARRAY;
 	test.rm_descr = "Test manager";
-	test.rm_end = 100;
+	test.rm_end = REGION_END;
 	error = rman_init(&test);
 	if (error) {
 		printf("Failed to initialize rman: %d\n", error);
 		return (error);
 	}
-	error = rman_manage_region(&test, 0, 100);
+	error = rman_manage_region(&test, REGION_START, REGION_END);
 	if (error) {
 		printf("Failed to manage region: %d\n", error);
 		unload();
@@ -282,6 +342,10 @@
 		assert_rman_ok();
 		rman_release_resource(r);
 	}
+	if (s != NULL) {
+		assert_rman_ok();
+		rman_release_resource(s);
+	}
 	assert_rman_ok();
 	error = rman_fini(&test);
 	if (error)



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