Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/systat Adapt to kernel buffer cache memort allocatio...
details: https://anonhg.NetBSD.org/src/rev/3d1f13dc6a2b
branches: trunk
changeset: 556916:3d1f13dc6a2b
user: pk <pk%NetBSD.org@localhost>
date: Tue Dec 30 12:52:48 2003 +0000
description:
Adapt to kernel buffer cache memort allocation changes.
Since the buffer headers do no longer exist as an array in the kernel anymore,
use the new CTL_KERN.KERN_BUF mib to fetch them from kernel space.
Also look at a vnode's specinfo field to properly associate an opened
block device special file with a mounted filesystem.
diffstat:
usr.bin/systat/bufcache.c | 189 +++++++++++++++++++++++++--------------------
1 files changed, 106 insertions(+), 83 deletions(-)
diffs (truncated from 325 to 300 lines):
diff -r 48bacfd0fe26 -r 3d1f13dc6a2b usr.bin/systat/bufcache.c
--- a/usr.bin/systat/bufcache.c Tue Dec 30 12:39:26 2003 +0000
+++ b/usr.bin/systat/bufcache.c Tue Dec 30 12:52:48 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bufcache.c,v 1.14 2003/12/07 07:28:05 christos Exp $ */
+/* $NetBSD: bufcache.c,v 1.15 2003/12/30 12:52:48 pk Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: bufcache.c,v 1.14 2003/12/07 07:28:05 christos Exp $");
+__RCSID("$NetBSD: bufcache.c,v 1.15 2003/12/30 12:52:48 pk Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -58,19 +58,11 @@
#include <string.h>
#include <unistd.h>
+#include <miscfs/specfs/specdev.h>
+
#include "systat.h"
#include "extern.h"
-/*
- * Definitions for the buffer free lists (from sys/kern/vfs_bio.c).
- */
-#define BQUEUES 4 /* number of free buffer queues */
-
-#define BQ_LOCKED 0 /* super-blocks &c */
-#define BQ_LRU 1 /* lru, useful buffers */
-#define BQ_AGE 2 /* rubbish */
-#define BQ_EMPTY 3 /* buffer headers with no memory */
-
#define VCACHE_SIZE 50
struct vcache {
@@ -80,34 +72,25 @@
};
struct ml_entry {
- int ml_count;
- long ml_size;
- long ml_valid;
+ u_int ml_count;
+ u_long ml_size;
+ u_long ml_valid;
struct mount *ml_addr;
+ LIST_ENTRY(ml_entry) ml_entries;
struct mount ml_mount;
- LIST_ENTRY(ml_entry) ml_entries;
};
static struct nlist namelist[] = {
-#define X_NBUF 0
- { "_nbuf" },
-#define X_BUF 1
- { "_buf" },
-#define X_BUFQUEUES 2
- { "_bufqueues" },
-#define X_BUFPAGES 3
- { "_bufpages" },
+#define X_BUFMEM 0
+ { "_bufmem" },
{ "" },
};
static struct vcache vcache[VCACHE_SIZE];
static LIST_HEAD(mount_list, ml_entry) mount_list;
-static int nbuf, bufpages, bufkb, pgwidth, kbwidth;
+static u_int nbuf, bufmem, pgwidth, kbwidth;
static struct uvmexp_sysctl uvmexp;
-static void *bufaddr;
-static struct buf *buf = NULL;
-static TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
static void vc_init(void);
static void ml_init(void);
@@ -138,10 +121,6 @@
void
labelbufcache(void)
{
- mvwprintw(wnd, 0, 0,
- "There are %*d metadata buffers using %*d kBytes of memory.",
- pgwidth, nbuf, kbwidth, bufkb);
- wclrtoeol(wnd);
wmove(wnd, 1, 0);
wclrtoeol(wnd);
wmove(wnd, 2, 0);
@@ -157,9 +136,15 @@
showbufcache(void)
{
int tbuf, i, lastrow;
- long tvalid, tsize;
+ double tvalid, tsize;
struct ml_entry *ml;
+ NREAD(X_BUFMEM, &bufmem, sizeof(bufmem));
+
+ mvwprintw(wnd, 0, 0,
+ "There are %*d metadata buffers using %*d kBytes of memory.",
+ pgwidth, nbuf, kbwidth, bufmem/1024);
+ wclrtoeol(wnd);
mvwprintw(wnd, 1, 0,
"There are %*llu pages for cached file data using %*llu kBytes of memory.",
pgwidth, (long long)uvmexp.filepages,
@@ -171,63 +156,60 @@
kbwidth, (long long) uvmexp.execpages * getpagesize() / 1024);
wclrtoeol(wnd);
- tbuf = tvalid = tsize = 0;
+ if (nbuf == 0 || bufmem == 0) {
+ wclrtobot(wnd);
+ return;
+ }
+
+ tbuf = 0;
+ tvalid = tsize = 0;
lastrow = 5; /* Leave room for header. */
for (i = lastrow, ml = LIST_FIRST(&mount_list); ml != NULL;
i++, ml = LIST_NEXT(ml, ml_entries)) {
+ int c = ml->ml_count;
+ double v = ml->ml_valid;
+ double s = ml->ml_size;
+
/* Display in window if enough room. */
if (i < getmaxy(wnd) - 2) {
mvwprintw(wnd, i, 0, "%-20.20s", ml->ml_addr == NULL ?
"NULL" : ml->ml_mount.mnt_stat.f_mntonname);
wprintw(wnd,
- " %6d %3d %8ld %3ld %8ld %3ld %3ld",
- ml->ml_count, (100 * ml->ml_count) / nbuf,
- ml->ml_valid, (100 * ml->ml_valid) / bufkb,
- ml->ml_size, (100 * ml->ml_size) / bufkb,
- (100 * ml->ml_valid) / ml->ml_size);
+ " %6d %3d %8ld %3.0f %8ld %3.0f %3.0f",
+ c, (100 * c) / nbuf,
+ (long)(v/1024), 100 * v / bufmem,
+ (long)(s/1024), 100 * s / bufmem,
+ 100 * v / s);
wclrtoeol(wnd);
lastrow = i;
}
/* Update statistics. */
- tbuf += ml->ml_count;
- tvalid += ml->ml_valid;
- tsize += ml->ml_size;
+ tbuf += c;
+ tvalid += v;
+ tsize += s;
}
wclrtobot(wnd);
mvwprintw(wnd, lastrow + 2, 0,
- "%-20s %6d %3d %8ld %3ld %8ld %3ld %3ld",
+ "%-20s %6d %3d %8ld %3.0f %8ld %3.0f %3.0f",
"Total:", tbuf, (100 * tbuf) / nbuf,
- tvalid, (100 * tvalid) / bufkb,
- tsize, (100 * tsize) / bufkb, tsize ? (100 * tvalid) / tsize : 0);
+ (long)(tvalid/1024), 100 * tvalid / bufmem,
+ (long)(tsize/1024), 100 * tsize / bufmem,
+ tsize != 0 ? ((100 * tvalid) / tsize) : 0);
}
int
initbufcache(void)
{
- if (namelist[X_NBUF].n_type == 0) {
+ if (namelist[0].n_type == 0) {
if (kvm_nlist(kd, namelist)) {
nlisterr(namelist);
return(0);
}
- if (namelist[X_NBUF].n_type == 0) {
- error("No namelist");
- return(0);
- }
}
- NREAD(X_NBUF, &nbuf, sizeof(nbuf));
- NREAD(X_BUFPAGES, &bufpages, sizeof(bufpages));
- bufkb = bufpages * sysconf(_SC_PAGESIZE) / 1024;
-
- if ((buf = malloc(nbuf * sizeof(struct buf))) == NULL) {
- error("malloc failed");
- die(0);
- }
- NREAD(X_BUF, &bufaddr, sizeof(bufaddr));
-
fetchuvmexp();
pgwidth = (int)(floor(log10((double)uvmexp.npages)) + 1);
kbwidth = (int)(floor(log10(uvmexp.npages * getpagesize() / 1024.0)) + 1);
@@ -254,37 +236,76 @@
void
fetchbufcache(void)
{
- int i, count;
+ int count;
struct buf *bp;
struct vnode *vn;
struct mount *mt;
struct ml_entry *ml;
+ int mib[2];
+ size_t size;
+ struct buf *buffers;
+ int extraslop = 0;
+ /* Re-read pages used for vnodes & executables */
fetchuvmexp();
- /* Re-read bufqueues lists and buffer cache headers */
- NREAD(X_BUFQUEUES, bufqueues, sizeof(bufqueues));
- KREAD(bufaddr, buf, sizeof(struct buf) * nbuf);
/* Initialise vnode cache and mount list. */
vc_init();
ml_init();
- for (i = 0; i < BQUEUES; i++) {
- for (bp = bufqueues[i].tqh_first; bp != NULL;
- bp = bp->b_freelist.tqe_next) {
- if (bp != NULL) {
- bp = (struct buf *)((u_long)bp + (u_long)buf -
- (u_long)bufaddr);
+
+ /* 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) {
+ error("can't get buffers size: %s\n", strerror(errno));
+ return;
+ }
+ if (size == 0)
+ return;
- if (bp->b_vp != NULL) {
- vn = vc_lookup(bp->b_vp);
- if (vn == NULL)
- break;
- if (vn->v_mount != NULL)
- mt = ml_lookup(vn->v_mount,
- bp->b_bufsize,
- bp->b_bcount);
- }
+ size += extraslop * sizeof(struct buf);
+ 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) {
+ free(buffers);
+ if (extraslop == 0) {
+ extraslop = 100;
+ goto again;
+ }
+ error("can't get buffers: %s\n", strerror(errno));
+ return;
+ }
+
+ nbuf = size / sizeof(struct buf);
+ for (bp = buffers; bp < buffers + nbuf; bp++) {
+ if (bp->b_vp != NULL) {
+ struct mount *mp;
+ vn = vc_lookup(bp->b_vp);
+ if (vn == NULL)
+ break;
+
+ mp = vn->v_mount;
+ /*
+ * References to mounted-on vnodes should be
+ * counted towards the mounted filesystem.
+ */
+ if (vn->v_type == VBLK && vn->v_specinfo != NULL) {
+ struct specinfo sp;
+ if (!KREAD(vn->v_specinfo, &sp, sizeof(sp)))
+ continue;
+ if (sp.si_mountpoint)
+ mp = sp.si_mountpoint;
}
+ if (mp != NULL)
+ mt = ml_lookup(mp,
+ bp->b_bufsize,
+ bp->b_bcount);
}
}
@@ -307,6 +328,8 @@
}
}
} while (count != 0);
+
+ free(buffers);
Home |
Main Index |
Thread Index |
Old Index