PERFORCE change 190649 for review
John Baldwin
jhb at FreeBSD.org
Sun Mar 27 21:36:40 UTC 2011
http://p4web.freebsd.org/@@190649?ac=10
Change 190649 by jhb at jhb_fiver on 2011/03/27 21:35:47
Checkpoint work on rman_release_region(). Need to flesh out regression tests.
Affected files ...
.. //depot/projects/pci/sys/kern/subr_rman.c#4 edit
.. //depot/projects/pci/sys/modules/rman/rman.c#5 edit
.. //depot/projects/pci/sys/sys/rman.h#3 edit
Differences ...
==== //depot/projects/pci/sys/kern/subr_rman.c#4 (text+ko) ====
@@ -227,6 +227,85 @@
}
int
+rman_release_region(struct rman *rm, u_long start, u_long end)
+{
+ struct resource_i *r, *s;
+
+ DPRINTF(("rman_release_region: <%s> request: start %#lx, end %#lx\n",
+ rm->rm_descr, start, end));
+
+ mtx_lock(rm->rm_mtx);
+
+ /* Skip entries before us. */
+ TAILQ_FOREACH(r, &rm->rm_list, r_link) {
+ if (r->r_end == ULONG_MAX)
+ break;
+ if (r->r_end + 1 >= start)
+ break;
+ }
+
+ /* If no entry found, this region is not managed. */
+ if (r == NULL) {
+ mtx_unlock(rm->rm_mtx);
+ return (ENOENT);
+ }
+
+ /* Ensure the entire range is managed. */
+ if (r->r_start > start) {
+ mtx_unlock(rm->rm_mtx);
+ return (ENOENT);
+ }
+ s = r;
+ while (s->r_end < end) {
+ t = TAILQ_NEXT(s, r_link);
+ if (t == NULL || t->r_start != s->r_end + 1) {
+ mtx_unlock(rm->rm_mtx);
+ return (ENOENT);
+ }
+ s = t;
+ }
+
+ /* Check if any part of the region is allocated. */
+ if (r->r_flags & RF_ALLOCATED || r->r_end < end) {
+ if (!(r->r_flags & RF_ALLOCATED))
+ KASSERT(TAILQ_NEXT(r, r_link)->r_flags & RF_ALLOCATED,
+ ("adjacent free regions"));
+ mtx_unlock(rm->rm_mtx);
+ return (ENOENT);
+ }
+
+ /*
+ * If the range exactly matches 'r', remove it, otherwise
+ * adjust 'r', possibly splitting it.
+ */
+ if (r->r_start == start && r->r_end == end) {
+ TAILQ_REMOVE(r, r_link);
+ free(r, M_RMAN);
+ } else if (r->r_start == start) {
+ KASSERT(end > r->r_end, ("resource entry too small"));
+ r->r_start = end + 1;
+ } else if (r->r_end == end) {
+ KASSERT(start < r->r_start, ("resource entry too small"));
+ r->r_end = start - 1;
+ } else {
+ KASSERT(r->r_start < start && end < r->r_end, ("resource entry too small"));
+ s = int_alloc_resource(M_NOWAIT);
+ if (s == NULL) {
+ mtx_unlock(rm->rm_mtx);
+ return (ENOMEM);
+ }
+ s->r_start = end + 1;
+ s->r_end = r->r_end;
+ s->r_rm = rm;
+ r->r_end = start - 1;
+ TAILQ_INSERT_AFTER(&rm->rm_list, r, s, r_link);
+ }
+ mtx_unlock(rm->rm_mtx);
+
+ return (0);
+}
+
+int
rman_init_from_resource(struct rman *rm, struct resource *r)
{
int rv;
==== //depot/projects/pci/sys/modules/rman/rman.c#5 (text+ko) ====
@@ -150,7 +150,7 @@
}
static void
-regression_tests(void)
+adjust_regression_tests(void)
{
int error;
@@ -295,6 +295,24 @@
assert_rman_ok();
}
+static void
+region_regression_tests(void)
+{
+
+ /* Clear any released resources. */
+ if (r != NULL) {
+ rman_release_resource(r);
+ r = NULL;
+ }
+ if (s != NULL) {
+ rman_release_resource(s);
+ s = NULL;
+ }
+ assert_rman_ok();
+
+
+}
+
static int
sysctl_rman_test(SYSCTL_HANDLER_ARGS)
{
@@ -303,12 +321,32 @@
error = sysctl_handle_int(oidp, &i, sizeof(i), req);
if (error || req->newptr == NULL || i == 0)
return (error);
- regression_tests();
+ switch (oip->arg2) {
+ case 0:
+ adjust_regression_tests();
+ break;
+ case 1:
+ region_regression_tests();
+ break;
+ }
return (error);
}
-SYSCTL_PROC(_debug_rman, OID_AUTO, test, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
- sysctl_rman_test, "I", "run regression tests");
+SYSCTL_PROC(_debug_rman, OID_AUTO, test_adjust, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
+ sysctl_rman_test, "I", "run regression tests for rman_adjust_resource()");
+SYSCTL_PROC(_debug_rman, OID_AUTO, test_region, CTLTYPE_INT | CTLFLAG_RW, 0, 1,
+ sysctl_rman_test, "I", "run regression tests for rman_release_region()");
+
+static int
+sysctl_rman_test_region(SYSCTL_HANDLER_ARGS)
+{
+ int error, i = 0;
+ error = sysctl_handle_int(oidp, &i, sizeof(i), req);
+ if (error || req->newptr == NULL || i == 0)
+ return (error);
+ region_regression_tests();
+ return (error);
+}
static int
load(void)
==== //depot/projects/pci/sys/sys/rman.h#3 (text+ko) ====
@@ -134,6 +134,7 @@
uint32_t rman_make_alignment_flags(uint32_t size);
int rman_manage_region(struct rman *rm, u_long start, u_long end);
int rman_is_region_manager(struct resource *r, struct rman *rm);
+int rman_release_region(struct rman *rm, u_long start, u_long end);
int rman_release_resource(struct resource *r);
struct resource *rman_reserve_resource(struct rman *rm, u_long start,
u_long end, u_long count,
More information about the p4-projects
mailing list