Date: Fri, 1 Apr 2011 16:33:12 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 190859 for review Message-ID: <201104011633.p31GXCcm076056@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@190859?ac=10 Change 190859 by jhb@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104011633.p31GXCcm076056>
