aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorAlfred Perlstein <alfred@FreeBSD.org>2001-04-27 22:24:45 +0000
committerAlfred Perlstein <alfred@FreeBSD.org>2001-04-27 22:24:45 +0000
commit93c7ba9f09faf57eecdd6b3fd945b94d6933437e (patch)
treeba07dc35a4025a54ebfed1713a2b2a3da7c14649 /sys/vm
parent4f3c11a65469e0b71064bcaf87335f44f82d904b (diff)
Notes
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_zone.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/sys/vm/vm_zone.c b/sys/vm/vm_zone.c
index 65c10deac9f0..4cddadc55123 100644
--- a/sys/vm/vm_zone.c
+++ b/sys/vm/vm_zone.c
@@ -414,31 +414,49 @@ zfree(vm_zone_t z, void *item)
static int
sysctl_vm_zone(SYSCTL_HANDLER_ARGS)
{
- int error, len;
- char tmpbuf[128];
+ int error, len, cnt;
+ const int linesize = 128; /* conservative */
+ char *tmpbuf, *offset;
vm_zone_t z;
char *p;
+ cnt = 0;
mtx_lock(&zone_mtx);
- len = snprintf(tmpbuf, sizeof(tmpbuf),
+ SLIST_FOREACH(z, &zlist, zent)
+ cnt++;
+ mtx_unlock(&zone_mtx);
+ MALLOC(tmpbuf, char *, (cnt == 0 ? 1 : cnt) * linesize,
+ M_TEMP, M_WAITOK);
+ len = snprintf(tmpbuf, linesize,
"\nITEM SIZE LIMIT USED FREE REQUESTS\n\n");
- error = SYSCTL_OUT(req, tmpbuf, SLIST_EMPTY(&zlist) ? len-1 : len);
+ if (cnt == 0)
+ tmpbuf[len - 1] = '\0';
+ error = SYSCTL_OUT(req, tmpbuf, cnt == 0 ? len-1 : len);
+ if (error || cnt == 0)
+ goto out;
+ offset = tmpbuf;
+ mtx_lock(&zone_mtx);
SLIST_FOREACH(z, &zlist, zent) {
+ if (cnt == 0) /* list may have changed size */
+ break;
mtx_lock(&z->zmtx);
- len = snprintf(tmpbuf, sizeof(tmpbuf),
+ len = snprintf(offset, linesize,
"%-12.12s %6.6u, %8.8u, %6.6u, %6.6u, %8.8u\n",
z->zname, z->zsize, z->zmax, (z->ztotal - z->zfreecnt),
z->zfreecnt, z->znalloc);
- for (p = tmpbuf + 12; p > tmpbuf && *p == ' '; --p)
+ mtx_unlock(&z->zmtx);
+ for (p = offset + 12; p > offset && *p == ' '; --p)
/* nothing */ ;
p[1] = ':';
- mtx_unlock(&z->zmtx);
- if (SLIST_NEXT(z, zent) == NULL)
- tmpbuf[len - 1] = 0;
- if ((error = SYSCTL_OUT(req, tmpbuf, len)) != 0)
- break;
+ cnt--;
+ offset += len;
}
mtx_unlock(&zone_mtx);
+ offset--;
+ *offset = '\0';
+ error = SYSCTL_OUT(req, tmpbuf, offset - tmpbuf);
+out:
+ FREE(tmpbuf, M_TEMP);
return (error);
}