interrupt statistics
Peter Pentchev
roam at ringlet.net
Thu Nov 20 07:37:09 PST 2003
On Thu, Nov 20, 2003 at 02:59:55PM +0100, Dag-Erling Sm?rgrav wrote:
> Peter Pentchev <roam at ringlet.net> writes:
> > This is easily fixed, e.g. by the attached. Note that I've only tested
> > the RELENG_4 patch, my 5.x machine is out of commission for the next few
> > days :( (and no, I couldn't test it on ref5 for obvious reasons related
> > to /dev/mem ;)
>
> Hmm, vmstat should uses sysctls, not /dev/mem. Perhaps you can make a
> patch for that too? :)
Awwighty, attached is a patch that converts getuptime() and dointr() to
use sysctl, and then adds the -a option to display all interrupts.
This one was tested on both RELENG_4 and HEAD (ref5) :)
G'luck,
Peter
--
Peter Pentchev roam at ringlet.net roam at sbnd.net roam at FreeBSD.org
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
This would easier understand fewer had omitted.
-------------- next part --------------
? src/usr.bin/vmstat/.depend
? src/usr.bin/vmstat/vmstat
? src/usr.bin/vmstat/vmstat.8.gz
Index: src/usr.bin/vmstat/Makefile
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/Makefile,v
retrieving revision 1.9
diff -u -r1.9 Makefile
--- src/usr.bin/vmstat/Makefile 8 Feb 2002 23:07:36 -0000 1.9
+++ src/usr.bin/vmstat/Makefile 20 Nov 2003 15:33:37 -0000
@@ -3,6 +3,7 @@
PROG= vmstat
MAN= vmstat.8
+CFLAGS+=-DVMSTAT_SYSCTL
BINGRP= kmem
BINMODE=2555
DPADD= ${LIBKVM} ${LIBDEVSTAT}
Index: src/usr.bin/vmstat/vmstat.8
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/vmstat.8,v
retrieving revision 1.25
diff -u -r1.25 vmstat.8
--- src/usr.bin/vmstat/vmstat.8 14 Apr 2003 07:22:25 -0000 1.25
+++ src/usr.bin/vmstat/vmstat.8 20 Nov 2003 15:33:37 -0000
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Nm
.\" .Op Fl fimst
-.Op Fl fimsz
+.Op Fl afimsz
.Op Fl c Ar count
.Op Fl M Ar core
.Op Fl N Ar system
@@ -62,6 +62,10 @@
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl a
+When used with
+.Fl i ,
+include statistics about interrupts that have never been generated.
.It Fl c
Repeat the display
.Ar count
Index: src/usr.bin/vmstat/vmstat.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/vmstat.c,v
retrieving revision 1.69
diff -u -r1.69 vmstat.c
--- src/usr.bin/vmstat/vmstat.c 9 Nov 2003 20:39:56 -0000 1.69
+++ src/usr.bin/vmstat/vmstat.c 20 Nov 2003 15:33:37 -0000
@@ -129,6 +129,7 @@
struct vmmeter sum, osum;
int winlines = 20;
+int aflag = 0;
int nflag = 0;
kvm_t *kd;
@@ -174,8 +175,11 @@
memf = nlistf = NULL;
interval = reps = todo = 0;
maxshowdevs = 2;
- while ((c = getopt(argc, argv, "c:fiM:mN:n:p:stw:z")) != -1) {
+ while ((c = getopt(argc, argv, "ac:fiM:mN:n:p:stw:z")) != -1) {
switch (c) {
+ case 'a':
+ aflag++;
+ break;
case 'c':
reps = atoi(optarg);
break;
@@ -239,24 +243,26 @@
if (nlistf != NULL || memf != NULL)
setgid(getgid());
- kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
- if (kd == 0)
- errx(1, "kvm_openfiles: %s", errbuf);
- setgid(getgid());
-
- if ((c = kvm_nlist(kd, namelist)) != 0) {
- if (c > 0) {
- warnx("undefined symbols:");
- for (c = 0;
- c < (int)(sizeof(namelist)/sizeof(namelist[0]));
- c++)
- if (namelist[c].n_type == 0)
- (void)fprintf(stderr, " %s",
- namelist[c].n_name);
- (void)fputc('\n', stderr);
- } else
- warnx("kvm_nlist: %s", kvm_geterr(kd));
- exit(1);
+ if (todo & ~INTRSTAT) {
+ kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
+ if (kd == 0)
+ errx(1, "kvm_openfiles: %s", errbuf);
+ setgid(getgid());
+
+ if ((c = kvm_nlist(kd, namelist)) != 0) {
+ if (c > 0) {
+ warnx("undefined symbols:");
+ for (c = 0;
+ c < (int)(sizeof(namelist)/sizeof(namelist[0]));
+ c++)
+ if (namelist[c].n_type == 0)
+ (void)fprintf(stderr, " %s",
+ namelist[c].n_name);
+ (void)fputc('\n', stderr);
+ } else
+ warnx("kvm_nlist: %s", kvm_geterr(kd));
+ exit(1);
+ }
}
if (todo & VMSTAT) {
@@ -386,8 +392,26 @@
static time_t now;
time_t uptime;
- if (boottime.tv_sec == 0)
+ if (boottime.tv_sec == 0) {
+#ifdef VMSTAT_SYSCTL
+ int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+ char *value;
+ size_t size;
+
+ if (sysctl(mib, 2, NULL, &size, NULL, NULL) == -1)
+ err(1, "sysctl(kern.boottime)");
+ if (size < sizeof(boottime))
+ errx(1, "sizeof(kern.boottime) < sizeof(timeval)");
+ value = malloc(size);
+ if (value == NULL)
+ errx(1, "malloc");
+ if (sysctl(mib, 2, value, &size, NULL, NULL) == -1)
+ err(1, "sysctl(kern.boottime)");
+ memcpy(&boottime, value, sizeof(boottime));
+#else /* VMSTAT_SYSCTL */
kread(X_BOOTTIME, &boottime, sizeof(boottime));
+#endif /* VMSTAT_SYSCTL */
+ }
(void)time(&now);
uptime = now - boottime.tv_sec;
if (uptime <= 0 || uptime > 60*60*24*365*10)
@@ -732,9 +756,42 @@
int i, istrnamlen;
size_t clen;
char *intrname, *tintrname;
+#ifdef VMSTAT_SYSCTL
+ int *mibcnt, *mibname;
+ size_t mibcntsize, mibnamesize;
+#endif /* VMSTAT_SYSCTL */
uptime = getuptime();
- nintr = namelist[X_EINTRCNT].n_value - namelist[X_INTRCNT].n_value;
+#ifdef VMSTAT_SYSCTL
+ /* Fetch the sysctl MIB's */
+ if (sysctlnametomib("hw.intrcnt", NULL, &mibcntsize) == -1)
+ err(1, "fetching the MIB for the hw.intrcnt sysctl");
+ mibcnt = malloc(mibcntsize * sizeof(int));
+ if (mibcnt == NULL)
+ errx(1, "malloc");
+ if (sysctlnametomib("hw.intrcnt", mibcnt, &mibcntsize) == -1)
+ err(1, "fetching the MIB for the hw.intrcnt sysctl");
+ if (sysctlnametomib("hw.intrnames", NULL, &mibnamesize) == -1)
+ err(1, "fetching the MIB for the hw.intrnames sysctl");
+ mibname = malloc(mibnamesize * sizeof(int));
+ if (mibname == NULL)
+ errx(1, "malloc");
+ if (sysctlnametomib("hw.intrnames", mibname, &mibnamesize) == -1)
+ err(1, "fetching the MIB for the hw.intrnames sysctl");
+
+ /* Fetch the arrays themselves */
+ if (sysctl(mibcnt, mibcntsize, NULL, &nintr, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrcnt)");
+ intrcnt = malloc((size_t)nintr);
+ if (sysctl(mibcnt, mibcntsize, intrcnt, &nintr, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrcnt)");
+ if (sysctl(mibname, mibnamesize, NULL, &inamlen, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrnames)");
+ intrname = malloc((size_t)inamlen);
+ if (sysctl(mibname, mibnamesize, intrname, &inamlen, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrnames)");
+#else /* VMSTAT_SYSCTL */
+ intr = namelist[X_EINTRCNT].n_value - namelist[X_INTRCNT].n_value;
inamlen =
namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;
intrcnt = malloc((size_t)nintr);
@@ -743,6 +800,7 @@
errx(1, "malloc");
kread(X_INTRCNT, intrcnt, (size_t)nintr);
kread(X_INTRNAMES, intrname, (size_t)inamlen);
+#endif /* VMSTAT_SYSCTL */
nintr /= sizeof(u_long);
tintrname = intrname;
istrnamlen = strlen("interrupt");
@@ -756,7 +814,7 @@
"rate");
inttotal = 0;
while (--nintr >= 0) {
- if (*intrcnt)
+ if (*intrcnt || (aflag && intrname[0]))
(void)printf("%-*s %20lu %10lu\n", istrnamlen, intrname,
*intrcnt, *intrcnt / uptime);
intrname += strlen(intrname) + 1;
@@ -829,7 +887,7 @@
usage()
{
(void)fprintf(stderr, "%s%s",
- "usage: vmstat [-imsz] [-c count] [-M core] [-N system] [-w wait]\n",
+ "usage: vmstat [-aimsz] [-c count] [-M core] [-N system] [-w wait]\n",
" [-n devs] [disks]\n");
exit(1);
}
-------------- next part --------------
Index: src/usr.bin/vmstat/Makefile
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/Makefile,v
retrieving revision 1.5.6.1
diff -u -r1.5.6.1 Makefile
--- src/usr.bin/vmstat/Makefile 25 Apr 2001 11:29:44 -0000 1.5.6.1
+++ src/usr.bin/vmstat/Makefile 20 Nov 2003 15:07:45 -0000
@@ -3,6 +3,7 @@
PROG= vmstat
MAN= vmstat.8
+CFLAGS+=-DVMSTAT_SYSCTL
CFLAGS+=-I${.CURDIR}/../../sys
BINGRP= kmem
BINMODE=2555
Index: src/usr.bin/vmstat/vmstat.8
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/vmstat.8,v
retrieving revision 1.16.2.5
diff -u -r1.16.2.5 vmstat.8
--- src/usr.bin/vmstat/vmstat.8 16 Aug 2001 13:17:13 -0000 1.16.2.5
+++ src/usr.bin/vmstat/vmstat.8 20 Nov 2003 12:21:23 -0000
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Nm
.\" .Op Fl fimst
-.Op Fl imsz
+.Op Fl aimsz
.Op Fl c Ar count
.Op Fl M Ar core
.Op Fl N Ar system
@@ -61,6 +61,10 @@
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl a
+When used with
+.Fl i ,
+include statistics about interrupts that have never been generated.
.It Fl c
Repeat the display
.Ar count
Index: src/usr.bin/vmstat/vmstat.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/vmstat/vmstat.c,v
retrieving revision 1.38.2.5
diff -u -r1.38.2.5 vmstat.c
--- src/usr.bin/vmstat/vmstat.c 20 Sep 2003 19:10:01 -0000 1.38.2.5
+++ src/usr.bin/vmstat/vmstat.c 20 Nov 2003 15:16:01 -0000
@@ -135,6 +135,7 @@
struct vmmeter sum, osum;
int winlines = 20;
+int aflag = 0;
int nflag = 0;
kvm_t *kd;
@@ -169,8 +170,11 @@
memf = nlistf = NULL;
interval = reps = todo = 0;
maxshowdevs = 2;
- while ((c = getopt(argc, argv, "c:fiM:mN:n:p:stw:z")) != -1) {
+ while ((c = getopt(argc, argv, "ac:fiM:mN:n:p:stw:z")) != -1) {
switch (c) {
+ case 'a':
+ aflag++;
+ break;
case 'c':
reps = atoi(optarg);
break;
@@ -238,22 +242,25 @@
if (nlistf != NULL || memf != NULL)
setgid(getgid());
- kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
- if (kd == 0)
- errx(1, "kvm_openfiles: %s", errbuf);
-
- if ((c = kvm_nlist(kd, namelist)) != 0) {
- if (c > 0) {
- warnx("undefined symbols:");
- for (c = 0;
- c < sizeof(namelist)/sizeof(namelist[0]); c++)
- if (namelist[c].n_type == 0)
- fprintf(stderr, " %s",
- namelist[c].n_name);
- (void)fputc('\n', stderr);
- } else
- warnx("kvm_nlist: %s", kvm_geterr(kd));
- exit(1);
+ if (todo & ~INTRSTAT) {
+ kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
+ if (kd == 0)
+ errx(1, "kvm_openfiles: %s", errbuf);
+
+ if ((c = kvm_nlist(kd, namelist)) != 0) {
+ if (c > 0) {
+ warnx("undefined symbols:");
+ for (c = 0;
+ c < sizeof(namelist)/sizeof(namelist[0]);
+ c++)
+ if (namelist[c].n_type == 0)
+ fprintf(stderr, " %s",
+ namelist[c].n_name);
+ (void)fputc('\n', stderr);
+ } else
+ warnx("kvm_nlist: %s", kvm_geterr(kd));
+ exit(1);
+ }
}
if (todo & VMSTAT) {
@@ -385,8 +392,26 @@
static time_t now, boottime;
time_t uptime;
- if (boottime == 0)
+ if (boottime == 0) {
+#ifdef VMSTAT_SYSCTL
+ int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+ char *value;
+ size_t size;
+
+ if (sysctl(mib, 2, NULL, &size, NULL, NULL) == -1)
+ err(1, "sysctl(kern.boottime)");
+ if (size < sizeof(boottime))
+ errx(1, "sizeof(kern.boottime) < sizeof(time_t)");
+ value = malloc(size);
+ if (value == NULL)
+ errx(1, "malloc");
+ if (sysctl(mib, 2, value, &size, NULL, NULL) == -1)
+ err(1, "sysctl(kern.boottime)");
+ memcpy(&boottime, value, sizeof(boottime));
+#else /* VMSTAT_SYSCTL */
kread(X_BOOTTIME, &boottime, sizeof(boottime));
+#endif /* VMSTAT_SYSCTL */
+ }
(void)time(&now);
uptime = now - boottime;
if (uptime <= 0 || uptime > 60*60*24*365*10)
@@ -722,10 +747,43 @@
{
register u_long *intrcnt, uptime;
register u_int64_t inttotal;
- register int nintr, inamlen;
+ int nintr, inamlen;
register char *intrname;
+#ifdef VMSTAT_SYSCTL
+ int *mibcnt, *mibname;
+ size_t mibcntsize, mibnamesize;
+#endif /* VMSTAT_SYSCTL */
uptime = getuptime();
+#ifdef VMSTAT_SYSCTL
+ /* Fetch the sysctl MIB's */
+ if (sysctlnametomib("hw.intrcnt", NULL, &mibcntsize) == -1)
+ err(1, "fetching the MIB for the hw.intrcnt sysctl");
+ mibcnt = malloc(mibcntsize * sizeof(int));
+ if (mibcnt == NULL)
+ errx(1, "malloc");
+ if (sysctlnametomib("hw.intrcnt", mibcnt, &mibcntsize) == -1)
+ err(1, "fetching the MIB for the hw.intrcnt sysctl");
+ if (sysctlnametomib("hw.intrnames", NULL, &mibnamesize) == -1)
+ err(1, "fetching the MIB for the hw.intrnames sysctl");
+ mibname = malloc(mibnamesize * sizeof(int));
+ if (mibname == NULL)
+ errx(1, "malloc");
+ if (sysctlnametomib("hw.intrnames", mibname, &mibnamesize) == -1)
+ err(1, "fetching the MIB for the hw.intrnames sysctl");
+
+ /* Fetch the arrays themselves */
+ if (sysctl(mibcnt, mibcntsize, NULL, &nintr, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrcnt)");
+ intrcnt = malloc((size_t)nintr);
+ if (sysctl(mibcnt, mibcntsize, intrcnt, &nintr, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrcnt)");
+ if (sysctl(mibname, mibnamesize, NULL, &inamlen, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrnames)");
+ intrname = malloc((size_t)inamlen);
+ if (sysctl(mibname, mibnamesize, intrname, &inamlen, NULL, NULL) == -1)
+ err(1, "sysctl(hw.intrnames)");
+#else /* VMSTAT_SYSCTL */
nintr = namelist[X_EINTRCNT].n_value - namelist[X_INTRCNT].n_value;
inamlen =
namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;
@@ -735,11 +793,12 @@
errx(1, "malloc");
kread(X_INTRCNT, intrcnt, (size_t)nintr);
kread(X_INTRNAMES, intrname, (size_t)inamlen);
+#endif /* VMSTAT_SYSCTL */
(void)printf("interrupt total rate\n");
inttotal = 0;
nintr /= sizeof(long);
while (--nintr >= 0) {
- if (*intrcnt)
+ if (*intrcnt || (aflag && intrname[0]))
(void)printf("%-12s %20lu %10lu\n", intrname,
*intrcnt, *intrcnt / uptime);
intrname += strlen(intrname) + 1;
@@ -917,7 +976,7 @@
usage()
{
(void)fprintf(stderr, "%s%s",
- "usage: vmstat [-imsz] [-c count] [-M core] [-N system] [-w wait]\n",
+ "usage: vmstat [-aimsz] [-c count] [-M core] [-N system] [-w wait]\n",
" [-n devs] [disks]\n");
exit(1);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20031120/c62f543f/attachment.bin
More information about the freebsd-hackers
mailing list