summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_rman.c
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2009-05-19 14:08:21 +0000
committeravg <avg@FreeBSD.org>2009-05-19 14:08:21 +0000
commit89d59b82b380fc829a85cee601c9e2b7f5ed04d6 (patch)
tree5a745940173191d2775994e8ab6468f9899dac2c /sys/kern/subr_rman.c
parent678fe0aa0365c8708e3c037618d7a573a43daa69 (diff)
downloadFreeBSD-src-89d59b82b380fc829a85cee601c9e2b7f5ed04d6.zip
FreeBSD-src-89d59b82b380fc829a85cee601c9e2b7f5ed04d6.tar.gz
sysctl_rman: report shared resources to devinfo
shared uses of a resource are recorded on a sub-list hanging off a main resource object on a main resource list; without this change a shared resource (e.g. irq) is reported only once by devinfo -r/-u; with this change the resource is reported for each driver that allocates it (which is even more than what vmstat -i -a reports). Approved by: jhb (mentor)
Diffstat (limited to 'sys/kern/subr_rman.c')
-rw-r--r--sys/kern/subr_rman.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index 8730a5b..0e53499 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -835,6 +835,7 @@ sysctl_rman(SYSCTL_HANDLER_ARGS)
int rman_idx, res_idx;
struct rman *rm;
struct resource_i *res;
+ struct resource_i *sres;
struct u_rman urm;
struct u_resource ures;
int error;
@@ -881,35 +882,44 @@ sysctl_rman(SYSCTL_HANDLER_ARGS)
*/
mtx_lock(rm->rm_mtx);
TAILQ_FOREACH(res, &rm->rm_list, r_link) {
- if (res_idx-- == 0) {
- bzero(&ures, sizeof(ures));
- ures.r_handle = (uintptr_t)res;
- ures.r_parent = (uintptr_t)res->r_rm;
- ures.r_device = (uintptr_t)res->r_dev;
- if (res->r_dev != NULL) {
- if (device_get_name(res->r_dev) != NULL) {
- snprintf(ures.r_devname, RM_TEXTLEN,
- "%s%d",
- device_get_name(res->r_dev),
- device_get_unit(res->r_dev));
- } else {
- strlcpy(ures.r_devname, "nomatch",
- RM_TEXTLEN);
+ if (res->r_sharehead != NULL) {
+ LIST_FOREACH(sres, res->r_sharehead, r_sharelink)
+ if (res_idx-- == 0) {
+ res = sres;
+ goto found;
}
- } else {
- ures.r_devname[0] = '\0';
- }
- ures.r_start = res->r_start;
- ures.r_size = res->r_end - res->r_start + 1;
- ures.r_flags = res->r_flags;
-
- mtx_unlock(rm->rm_mtx);
- error = SYSCTL_OUT(req, &ures, sizeof(ures));
- return (error);
}
+ else if (res_idx-- == 0)
+ goto found;
}
mtx_unlock(rm->rm_mtx);
return (ENOENT);
+
+found:
+ bzero(&ures, sizeof(ures));
+ ures.r_handle = (uintptr_t)res;
+ ures.r_parent = (uintptr_t)res->r_rm;
+ ures.r_device = (uintptr_t)res->r_dev;
+ if (res->r_dev != NULL) {
+ if (device_get_name(res->r_dev) != NULL) {
+ snprintf(ures.r_devname, RM_TEXTLEN,
+ "%s%d",
+ device_get_name(res->r_dev),
+ device_get_unit(res->r_dev));
+ } else {
+ strlcpy(ures.r_devname, "nomatch",
+ RM_TEXTLEN);
+ }
+ } else {
+ ures.r_devname[0] = '\0';
+ }
+ ures.r_start = res->r_start;
+ ures.r_size = res->r_end - res->r_start + 1;
+ ures.r_flags = res->r_flags;
+
+ mtx_unlock(rm->rm_mtx);
+ error = SYSCTL_OUT(req, &ures, sizeof(ures));
+ return (error);
}
SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman,
OpenPOWER on IntegriCloud