Add PTRTOUINT64() and UINT64TOPTR() macros to sys/sysctl.h for use by
kern.proc, kern.proc2, kern.lwp, and kern.buf. Define more MIB for kern.buf so that specific buffers can be selected (only all/all is supported right now), and use a 32/64 bit agnostic structure for communcating buffer information to userland. Convert systat to the new kern.buf method. Clean up the vm.buf* handling a little. There's no actual need to record the dynamically assigned OIDs, since sysctl_data can tell us what we're looking at. Oh, and fix a typo in a comment.
This commit is contained in:
parent
cb57c6f8e9
commit
caea20e952
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_bio.c,v 1.116 2004/02/16 09:34:15 yamt Exp $ */
|
||||
/* $NetBSD: vfs_bio.c,v 1.117 2004/02/19 03:56:30 atatat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -81,7 +81,7 @@
|
|||
#include "opt_softdep.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.116 2004/02/16 09:34:15 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.117 2004/02/19 03:56:30 atatat Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -1434,54 +1434,96 @@ fail:;
|
|||
return nbusy;
|
||||
}
|
||||
|
||||
static void
|
||||
sysctl_fillbuf(struct buf *i, struct buf_sysctl *o)
|
||||
{
|
||||
|
||||
o->b_flags = i->b_flags;
|
||||
o->b_error = i->b_error;
|
||||
o->b_prio = i->b_prio;
|
||||
o->b_dev = i->b_dev;
|
||||
o->b_bufsize = i->b_bufsize;
|
||||
o->b_bcount = i->b_bcount;
|
||||
o->b_resid = i->b_resid;
|
||||
o->b_addr = PTRTOUINT64(i->b_un.b_addr);
|
||||
o->b_blkno = i->b_blkno;
|
||||
o->b_rawblkno = i->b_rawblkno;
|
||||
o->b_iodone = PTRTOUINT64(i->b_iodone);
|
||||
o->b_proc = PTRTOUINT64(i->b_proc);
|
||||
o->b_vp = PTRTOUINT64(i->b_vp);
|
||||
o->b_saveaddr = PTRTOUINT64(i->b_saveaddr);
|
||||
o->b_lblkno = i->b_lblkno;
|
||||
}
|
||||
|
||||
#define KERN_BUFSLOP 20
|
||||
static int
|
||||
sysctl_dobuf(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct buf_sysctl bs;
|
||||
char *dp;
|
||||
u_int i, elem_size;
|
||||
size_t len, buflen, needed;
|
||||
int error, s;
|
||||
u_int i, op, arg;
|
||||
size_t len, needed, elem_size, out_size;
|
||||
int error, s, elem_count;
|
||||
|
||||
if (namelen == 1 && name[0] == CTL_QUERY)
|
||||
return (sysctl_query(SYSCTLFN_CALL(rnode)));
|
||||
|
||||
if (namelen != 4)
|
||||
return (EINVAL);
|
||||
|
||||
dp = oldp;
|
||||
len = buflen = oldp != NULL ? *oldlenp : 0;
|
||||
len = (oldp != NULL) ? *oldlenp : 0;
|
||||
op = name[0];
|
||||
arg = name[1];
|
||||
elem_size = name[2];
|
||||
elem_count = name[3];
|
||||
out_size = MIN(sizeof(bs), elem_size);
|
||||
|
||||
/*
|
||||
* at the moment, these are just "placeholders" to make the
|
||||
* API for retrieving kern.buf data more extensible in the
|
||||
* future.
|
||||
*
|
||||
* XXX kern.buf currently has "netbsd32" issues. hopefully
|
||||
* these will be resolved at a later point.
|
||||
*/
|
||||
if (op != KERN_BUF_ALL || arg != KERN_BUF_ALL ||
|
||||
elem_size < 1 || elem_count < 0)
|
||||
return (EINVAL);
|
||||
|
||||
error = 0;
|
||||
needed = 0;
|
||||
elem_size = sizeof(struct buf);
|
||||
|
||||
s = splbio();
|
||||
simple_lock(&bqueue_slock);
|
||||
for (i = 0; i < BQUEUES; i++) {
|
||||
TAILQ_FOREACH(bp, &bufqueues[i], b_freelist) {
|
||||
if (len >= elem_size) {
|
||||
error = copyout(bp, dp, elem_size);
|
||||
if (len >= elem_size && elem_count > 0) {
|
||||
sysctl_fillbuf(bp, &bs);
|
||||
error = copyout(&bs, dp, out_size);
|
||||
if (error)
|
||||
goto cleanup;
|
||||
dp += elem_size;
|
||||
len -= elem_size;
|
||||
}
|
||||
needed += elem_size;
|
||||
if (elem_count > 0) {
|
||||
needed += elem_size;
|
||||
if (elem_count != INT_MAX)
|
||||
elem_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
simple_unlock(&bqueue_slock);
|
||||
splx(s);
|
||||
|
||||
if (oldp != NULL) {
|
||||
*oldlenp = (char *)dp - (char *)oldp;
|
||||
if (needed > *oldlenp)
|
||||
error = ENOMEM;
|
||||
} else {
|
||||
needed += KERN_BUFSLOP;
|
||||
*oldlenp = needed;
|
||||
}
|
||||
*oldlenp = needed;
|
||||
if (oldp == NULL)
|
||||
*oldlenp += KERN_BUFSLOP * sizeof(struct buf);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int sysctlnum_bufcache, sysctlnum_bufmemhiwater, sysctlnum_bufmemlowater;
|
||||
|
||||
static int
|
||||
sysctl_bufvm_update(SYSCTLFN_ARGS)
|
||||
{
|
||||
|
@ -1495,7 +1537,7 @@ sysctl_bufvm_update(SYSCTLFN_ARGS)
|
|||
if (error || newp == NULL)
|
||||
return (error);
|
||||
|
||||
if (rnode->sysctl_num == sysctlnum_bufcache) {
|
||||
if (rnode->sysctl_data == &bufcache) {
|
||||
if (t < 0 || t > 100)
|
||||
return (EINVAL);
|
||||
bufcache = t;
|
||||
|
@ -1505,9 +1547,9 @@ sysctl_bufvm_update(SYSCTLFN_ARGS)
|
|||
/* Ensure a reasonable minimum value */
|
||||
bufmem_lowater = 64 * 1024;
|
||||
|
||||
} else if (rnode->sysctl_num == sysctlnum_bufmemlowater) {
|
||||
} else if (rnode->sysctl_data == &bufmem_lowater) {
|
||||
bufmem_lowater = t;
|
||||
} else if (rnode->sysctl_num == sysctlnum_bufmemhiwater) {
|
||||
} else if (rnode->sysctl_data == &bufmem_hiwater) {
|
||||
bufmem_hiwater = t;
|
||||
} else
|
||||
return (EINVAL);
|
||||
|
@ -1536,33 +1578,24 @@ SYSCTL_SETUP(sysctl_kern_buf_setup, "sysctl kern.buf subtree setup")
|
|||
|
||||
SYSCTL_SETUP(sysctl_vm_buf_setup, "sysctl vm.buf* subtree setup")
|
||||
{
|
||||
struct sysctlnode *rnode;
|
||||
|
||||
sysctl_createv(SYSCTL_PERMANENT,
|
||||
CTLTYPE_NODE, "vm", NULL,
|
||||
NULL, 0, NULL, 0,
|
||||
CTL_VM, CTL_EOL);
|
||||
|
||||
rnode = NULL;
|
||||
if (sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufcache", &rnode,
|
||||
sysctl_bufvm_update, 0, &bufcache, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL) == 0)
|
||||
sysctlnum_bufcache = rnode->sysctl_num;
|
||||
|
||||
rnode = NULL;
|
||||
if (sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufmem_lowater", &rnode,
|
||||
sysctl_bufvm_update, 0, &bufmem_lowater, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL) == 0)
|
||||
sysctlnum_bufmemlowater = rnode->sysctl_num;
|
||||
|
||||
rnode = NULL;
|
||||
if (sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufmem_hiwater", &rnode,
|
||||
sysctl_bufvm_update, 0, &bufmem_hiwater, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL) == 0)
|
||||
sysctlnum_bufmemhiwater = rnode->sysctl_num;
|
||||
sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufcache", NULL,
|
||||
sysctl_bufvm_update, 0, &bufcache, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL);
|
||||
sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufmem_lowater", NULL,
|
||||
sysctl_bufvm_update, 0, &bufmem_lowater, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL);
|
||||
sysctl_createv(SYSCTL_PERMANENT|SYSCTL_READWRITE,
|
||||
CTLTYPE_INT, "bufmem_hiwater", NULL,
|
||||
sysctl_bufvm_update, 0, &bufmem_hiwater, 0,
|
||||
CTL_VM, CTL_CREATE, CTL_EOL);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sysctl.h,v 1.108 2004/02/13 11:36:23 wiz Exp $ */
|
||||
/* $NetBSD: sysctl.h,v 1.109 2004/02/19 03:56:30 atatat Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -382,6 +382,13 @@ struct kinfo_proc {
|
|||
} kp_eproc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert pointer to 64 bit unsigned integer for struct
|
||||
* kinfo_proc2, etc.
|
||||
*/
|
||||
#define PTRTOUINT64(p) ((u_int64_t)(uintptr_t)(p))
|
||||
#define UINT64TOPTR(u) ((void *)(uintptr_t)(u))
|
||||
|
||||
/*
|
||||
* KERN_PROC2 subtype ops return arrays of relatively fixed size
|
||||
* structures of process info. Use 8 byte alignment, and new
|
||||
|
@ -573,7 +580,7 @@ struct kinfo_lwp {
|
|||
}
|
||||
|
||||
/*
|
||||
* kern.drivers returns and array of these.
|
||||
* kern.drivers returns an array of these.
|
||||
*/
|
||||
|
||||
struct kinfo_drivers {
|
||||
|
@ -582,6 +589,38 @@ struct kinfo_drivers {
|
|||
char d_name[24];
|
||||
};
|
||||
|
||||
/*
|
||||
* KERN_BUF subtypes, like KERN_PROC2, where the four following mib
|
||||
* entries specify "which type of buf", "which particular buf",
|
||||
* "sizeof buf", and "how many". Currently, only "all buf" is
|
||||
* defined.
|
||||
*/
|
||||
#define KERN_BUF_ALL 0 /* all buffers */
|
||||
|
||||
/*
|
||||
* kern.buf returns an array of these structures, which are designed
|
||||
* both to be immune to 32/64 bit emulation issues and to provide
|
||||
* backwards compatibility. Note that the order here differs slightly
|
||||
* from the real struct buf in order to achieve proper 64 bit
|
||||
* alignment.
|
||||
*/
|
||||
struct buf_sysctl {
|
||||
uint32_t b_flags; /* LONG: B_* flags */
|
||||
int32_t b_error; /* INT: Errno value */
|
||||
int32_t b_prio; /* INT: Hint for buffer queue discipline */
|
||||
uint32_t b_dev; /* DEV_T: Device associated with buffer */
|
||||
uint64_t b_bufsize; /* LONG: Allocated buffer size */
|
||||
uint64_t b_bcount; /* LONG: Valid bytes in buffer */
|
||||
uint64_t b_resid; /* LONG: Remaining I/O */
|
||||
uint64_t b_addr; /* CADDR_T: Memory, superblocks, indirect... */
|
||||
uint64_t b_blkno; /* DADDR_T: Underlying physical block number */
|
||||
uint64_t b_rawblkno; /* DADDR_T: Raw underlying physical block */
|
||||
uint64_t b_iodone; /* PTR: Function called upon completion */
|
||||
uint64_t b_proc; /* PTR: Associated proc if B_PHYS set */
|
||||
uint64_t b_vp; /* PTR: File vnode */
|
||||
uint64_t b_saveaddr; /* PTR: Original b_addr for physio */
|
||||
uint64_t b_lblkno; /* DADDR_T: Logical block number */
|
||||
};
|
||||
|
||||
/*
|
||||
* CTL_HW identifiers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bufcache.c,v 1.15 2003/12/30 12:52:48 pk Exp $ */
|
||||
/* $NetBSD: bufcache.c,v 1.16 2004/02/19 03:56:30 atatat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: bufcache.c,v 1.15 2003/12/30 12:52:48 pk Exp $");
|
||||
__RCSID("$NetBSD: bufcache.c,v 1.16 2004/02/19 03:56:30 atatat Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -237,13 +237,12 @@ void
|
|||
fetchbufcache(void)
|
||||
{
|
||||
int count;
|
||||
struct buf *bp;
|
||||
struct buf_sysctl *bp, *buffers;
|
||||
struct vnode *vn;
|
||||
struct mount *mt;
|
||||
struct ml_entry *ml;
|
||||
int mib[2];
|
||||
int mib[6];
|
||||
size_t size;
|
||||
struct buf *buffers;
|
||||
int extraslop = 0;
|
||||
|
||||
/* Re-read pages used for vnodes & executables */
|
||||
|
@ -254,25 +253,29 @@ fetchbufcache(void)
|
|||
ml_init();
|
||||
|
||||
/* Get metadata buffers */
|
||||
again:
|
||||
size = 0;
|
||||
buffers = NULL;
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_BUF;
|
||||
if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) {
|
||||
mib[2] = KERN_BUF_ALL;
|
||||
mib[3] = KERN_BUF_ALL;
|
||||
mib[4] = (int)sizeof(struct buf_sysctl);
|
||||
mib[5] = INT_MAX; /* we want them all */
|
||||
again:
|
||||
if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
|
||||
error("can't get buffers size: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
size += extraslop * sizeof(struct buf);
|
||||
size += extraslop * sizeof(struct buf_sysctl);
|
||||
buffers = malloc(size);
|
||||
if (buffers == NULL) {
|
||||
error("can't allocate buffers: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (sysctl(mib, 2, buffers, &size, NULL, 0) < 0) {
|
||||
if (sysctl(mib, 6, buffers, &size, NULL, 0) < 0) {
|
||||
free(buffers);
|
||||
if (extraslop == 0) {
|
||||
extraslop = 100;
|
||||
|
@ -282,11 +285,11 @@ again:
|
|||
return;
|
||||
}
|
||||
|
||||
nbuf = size / sizeof(struct buf);
|
||||
nbuf = size / sizeof(struct buf_sysctl);
|
||||
for (bp = buffers; bp < buffers + nbuf; bp++) {
|
||||
if (bp->b_vp != NULL) {
|
||||
if (UINT64TOPTR(bp->b_vp) != NULL) {
|
||||
struct mount *mp;
|
||||
vn = vc_lookup(bp->b_vp);
|
||||
vn = vc_lookup(UINT64TOPTR(bp->b_vp));
|
||||
if (vn == NULL)
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue