| From | Sent On | Attachments |
|---|---|---|
| John Baldwin | Mar 27, 2011 2:36 pm |
| Subject: | PERFORCE change 190649 for review | |
|---|---|---|
| From: | John Baldwin (jh...@FreeBSD.org) | |
| Date: | Mar 27, 2011 2:36:06 pm | |
| List: | org.freebsd.p4-projects | |
http://p4web.freebsd.org/@@190649?ac=10
Change 190649 by jhb@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,
_______________________________________________ p4-p...@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/p4-projects To unsubscribe, send any mail to "p4-p...@freebsd.org"





