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)
This commit is contained in:
avg 2009-05-19 14:08:21 +00:00
parent 678fe0aa03
commit 89d59b82b3

View File

@ -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,