PERFORCE change 190859 for review

John Baldwin jhb at FreeBSD.org
Fri Apr 1 16:33:18 UTC 2011


http://p4web.freebsd.org/@@190859?ac=10

Change 190859 by jhb at jhb_kavik on 2011/04/01 01:51:27

	Flesh out release region tests.

Affected files ...

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

Differences ...

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

@@ -1,5 +1,5 @@
 /*-
- * Regression tests for rman_adjust_resource().
+ * Regression tests for rman_adjust_resource() and rman_release_resource().
  */
 
 #include <sys/param.h>
@@ -301,6 +301,34 @@
 };
 
 static void
+assert_rman_hole(u_long start, u_long end)
+{
+	struct resource_i *i;
+
+	TAILQ_FOREACH(i, &test.rm_list, r_link) {
+		KASSERT(i->r_end < start || i->r_start > end,
+		    ("region is not free"));
+	}
+}
+
+static void
+assert_rman_managed(u_long start, u_long end)
+{
+	struct resource_i *i;
+
+	TAILQ_FOREACH(i, &test.rm_list, r_link) {
+		if (i->r_end < start)
+			continue;
+		if (i->r_start <= start) {
+			if (end <= i->r_end)
+				return;
+			start = i->r_end + 1;
+		}
+	}
+	panic("region (%lx, %lx) is not managed", start, end);
+}
+
+static void
 assert_rman_regions(struct region *regions, int count)
 {
 	struct resource_i *i;
@@ -340,7 +368,45 @@
 region_regression_tests(void)
 {
 	struct region regions[3];
+	int error;
 
+#define RELEASE_SHOULD_FAIL(start, end, err) do {			\
+	error = rman_release_region(&test, (start), (end));		\
+	if (error == (err))						\
+		printf("Correctly failed to release (%x, %x)\n",	\
+		    (start), (end));					\
+	else {								\
+		if (error)						\
+			printf("Failed to release (%x, %x) with %d\n",	\
+			    (start), (end), error);			\
+		else							\
+			printf("Incorrectly released (%lx, %lx)\n",	\
+			    rman_get_start(r), rman_get_end(r));	\
+		return;							\
+	}								\
+} while (0)
+
+#define RELEASE_SHOULD_WORK(start, end) do {				\
+	error = rman_release_region(&test, (start), (end));		\
+	if (error) {							\
+		printf("Failed to release (%x, %x) with %d\n",		\
+		    (start), (end), error);				\
+		return;							\
+	}								\
+	printf("Released (%x, %x)\n", (start), (end));			\
+	assert_rman_hole((start), (end));				\
+} while (0)
+
+#define MANAGE_SHOULD_WORK(start, end) do {				\
+	error = rman_manage_region(&test, (start), (end));		\
+	if (error) {							\
+		printf("Failed to manage (%x, %x) with %d\n",		\
+		    (start), (end), error);				\
+		return;							\
+	}								\
+	printf("Managed (%x, %x)\n", (start), (end));			\
+	assert_rman_managed((start), (end));				\
+} while (0)
 
 	/* Clear any released resources. */
 	if (r != NULL) {
@@ -358,8 +424,84 @@
 	regions[0].end = REGION_END;
 	assert_rman_regions(regions, 1);
 
+	/* Should not be able to release regions outside of bounds. */
+	RELEASE_SHOULD_FAIL(REGION_START - 0x10, REGION_START + 0x10, ENOENT);
+	RELEASE_SHOULD_FAIL(REGION_END - 0x10, REGION_END + 0x10, ENOENT);
+
+	/* Free entire rman and reallocate it. */
+	RELEASE_SHOULD_WORK(REGION_START, REGION_END);
+	assert_rman_regions(NULL, 0);
+	MANAGE_SHOULD_WORK(REGION_START, REGION_END);
+	assert_rman_regions(regions, 1);
+	
 	/* Release some holes to end up with two regions. */
-	rman_release_region
+	RELEASE_SHOULD_WORK(REGION_START, REGION_START + 0xf);
+	regions[0].start = REGION_START + 0x10;
+	assert_rman_regions(regions, 1);
+	RELEASE_SHOULD_WORK(REGION_END - 0xf, REGION_END);
+	regions[0].end = REGION_END - 0x10;
+	assert_rman_regions(regions, 1);
+	RELEASE_SHOULD_WORK(REGION_START + 0x41, REGION_END - 0x41);
+	regions[1].end = regions[0].end;
+	regions[0].end = REGION_START + 0x40;
+	regions[1].start = REGION_END - 0x40;
+	assert_rman_regions(regions, 2);
+
+	/* Releasing already released regions should fail. */
+	RELEASE_SHOULD_FAIL(REGION_START, REGION_START + 0x8, ENOENT);
+	RELEASE_SHOULD_FAIL(REGION_START + 0x40, REGION_END - 0x41, ENOENT);
+	RELEASE_SHOULD_FAIL(REGION_END - 0x8, REGION_END, ENOENT);
+
+	/* Allocate a resource from the first region. */
+	r = rman_reserve_resource(&test, REGION_START + 0x20,
+	    REGION_START + 0x2f, 0x10, 0, NULL);
+	if (r == NULL) {
+		printf("Failed to allocate resource\n");
+		return;
+	}
+	printf("Allocated (%lx, %lx)\n", rman_get_start(r), rman_get_end(r));
+	assert_rman_regions(regions, 2);
+
+	/* Should not be able to release regions that overlap 'r'. */
+	RELEASE_SHOULD_FAIL(rman_get_start(r), rman_get_end(r), EBUSY);
+	RELEASE_SHOULD_FAIL(REGION_START + 0x10, rman_get_start(r), EBUSY);
+	RELEASE_SHOULD_FAIL(rman_get_end(r), REGION_START + 0x40, EBUSY);
+	RELEASE_SHOULD_FAIL(REGION_START + 0x10, REGION_START + 0x40, EBUSY);
+	assert_rman_regions(regions, 2);
+
+	/* Should be able to release regions around 'r'. */
+	RELEASE_SHOULD_WORK(REGION_START + 0x10, rman_get_start(r) - 1);
+	regions[0].start = rman_get_start(r);
+	assert_rman_regions(regions, 2);
+	RELEASE_SHOULD_WORK(rman_get_end(r) + 1, REGION_START + 0x40);
+	regions[0].end = rman_get_end(r);
+	assert_rman_regions(regions, 2);
+
+	/* Should be able to release a single address in a region. */
+	RELEASE_SHOULD_WORK(regions[1].start + 0x10, regions[1].start + 0x10);
+	regions[2].end = regions[1].end;
+	regions[2].start = regions[1].start + 0x10 + 1;
+	regions[1].end = regions[1].start + 0x10 - 1;
+	assert_rman_regions(regions, 3);
+
+	/* Fill in all the holes. */
+	MANAGE_SHOULD_WORK(regions[2].end + 1, REGION_END);
+	regions[2].end = REGION_END;
+	assert_rman_regions(regions, 3);
+	MANAGE_SHOULD_WORK(REGION_START, regions[0].start - 1);
+	regions[0].start = REGION_START;
+	assert_rman_regions(regions, 3);
+	MANAGE_SHOULD_WORK(regions[1].end + 1, regions[2].start - 1);
+	regions[1].end = REGION_END;
+	assert_rman_regions(regions, 2);
+	MANAGE_SHOULD_WORK(regions[0].end + 1, regions[1].start - 1);
+	regions[0].end = REGION_END;
+	assert_rman_regions(regions, 1);
+	assert_rman_ok();
+
+	rman_release_resource(r);
+	assert_rman_regions(regions, 1);
+	assert_rman_ok();
 }
 
 static int


More information about the p4-projects mailing list