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