Subject: vmstat addition for vmtotal struct printout
To: None <current-users@netbsd.org>
From: Havard Eidnes <he@netbsd.org>
List: current-users
Date: 03/10/2005 14:59:17
Hi,

it appears that

1) there presently is no way to get the number of processes in
   the individual states in the vmtotal struct printed

2) the virtual memory values of the vmtotal structure are also not
   presented by vmstat

The following diff attempts to correct this.

Comments? 

Regards,

- Havard

------------------------------

Index: vmstat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/vmstat/vmstat.c,v
retrieving revision 1.129
diff -u -r1.129 vmstat.c
--- vmstat.c	26 Feb 2005 21:19:18 -0000	1.129
+++ vmstat.c	10 Mar 2005 12:49:36 -0000
@@ -237,6 +237,7 @@
 #define	HISTDUMP	1<<7
 #define	HASHSTAT	1<<8
 #define	HASHLIST	1<<9
+#define	VMTOTAL		1<<10
 
 void	cpustats(void);
 void	deref_kptr(const void *, void *, size_t, const char *);
@@ -249,6 +250,8 @@
 void	dopoolcache(struct pool *, int);
 void	dosum(void);
 void	dovmstat(struct timespec *, int);
+void	print_total_hdr(void);
+void	dovmtotal(struct timespec *, int);
 void	kread(int, void *, size_t);
 void	needhdr(int);
 long	getuptime(void);
@@ -285,7 +288,7 @@
 	reps = todo = verbose = wide = 0;
 	interval.tv_sec = 0;
 	interval.tv_nsec = 0;
-	while ((c = getopt(argc, argv, "c:efh:HilLM:mN:su:UvWw:")) != -1) {
+	while ((c = getopt(argc, argv, "c:efh:HilLM:mN:stu:UvWw:")) != -1) {
 		switch (c) {
 		case 'c':
 			reps = atoi(optarg);
@@ -323,6 +326,9 @@
 		case 's':
 			todo |= SUMSTAT;
 			break;
+		case 't':
+			todo |= VMTOTAL;
+			break;
 		case 'u':
 			histname = optarg;
 			/* FALLTHROUGH */
@@ -417,7 +423,7 @@
 	 * VMSTAT/dovmstat() output. So perform the interval/reps handling
 	 * for it here.
 	 */
-	if ((todo & VMSTAT) == 0) {
+	if ((todo & (VMSTAT|VMTOTAL)) == 0) {
 		for (;;) {
 			if (todo & (HISTLIST|HISTDUMP)) {
 				if ((todo & (HISTLIST|HISTDUMP)) ==
@@ -461,8 +467,15 @@
 				break;
 			nanosleep(&interval, NULL);
 		}
-	} else
-		dovmstat(&interval, reps);
+	} else {
+		if ((todo & (VMSTAT|VMTOTAL)) == (VMSTAT|VMTOTAL)) {
+			errx(1, "you may not both do vmstat and vmtotal");
+		}
+		if (todo & VMSTAT)
+			dovmstat(&interval, reps);
+		if (todo & VMTOTAL)
+			dovmtotal(&interval, reps);
+	}
 	exit(0);
 }
 
@@ -520,6 +533,67 @@
 int	hz, hdrcnt;
 
 void
+print_total_hdr()
+{
+
+	(void)printf("procs            memory\n");
+	(void)printf("ru dw pw sl sw");
+	(void)printf("   total-v  active-v  active-r");
+	(void)printf(" vm-sh avm-sh rm-sh arm-sh free\n");
+	hdrcnt = winlines - 2;
+}
+
+void
+dovmtotal(struct timespec *interval, int reps)
+{
+	struct vmtotal total;
+	int mib[2];
+	size_t size;
+
+	(void)signal(SIGCONT, needhdr);
+
+	for (hdrcnt = 1;;) {
+		if (!--hdrcnt)
+			print_total_hdr();
+		if (memf != NULL) {
+			printf("Unable to get vmtotals from crash dump.\n");
+			memset(&total, 0, sizeof(total));
+		} else {
+			size = sizeof(total);
+			mib[0] = CTL_VM;
+			mib[1] = VM_METER;
+			if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) {
+				printf("Can't get vmtotals: %s\n",
+				    strerror(errno));
+				memset(&total, 0, sizeof(total));
+			}
+		}
+		printf("%2d ", total.t_rq);
+		printf("%2d ", total.t_dw);
+		printf("%2d ", total.t_pw);
+		printf("%2d ", total.t_sl);
+		printf("%2d ", total.t_sw);
+
+		printf("%9d ", total.t_vm);
+		printf("%9d ", total.t_avm);
+		printf("%9d ", total.t_arm);
+		printf("%5d ", total.t_vmshr);
+		printf("%6d ", total.t_avmshr);
+		printf("%5d ", total.t_rmshr);
+		printf("%6d ", total.t_armshr);
+		printf("%5d",  total.t_free);
+
+		putchar('\n');
+
+		(void)fflush(stdout);
+		if (reps >= 0 && --reps <= 0)
+			break;
+
+		nanosleep(interval, NULL);
+	}
+}
+
+void
 dovmstat(struct timespec *interval, int reps)
 {
 	struct vmtotal total;
Index: vmstat.1
===================================================================
RCS file: /cvsroot/src/usr.bin/vmstat/vmstat.1,v
retrieving revision 1.14
diff -u -r1.14 vmstat.1
--- vmstat.1	26 Jan 2005 13:41:47 -0000	1.14
+++ vmstat.1	10 Mar 2005 12:49:36 -0000
@@ -68,7 +68,7 @@
 .Nd report virtual memory statistics
 .Sh SYNOPSIS
 .Nm
-.Op Fl efHiLlmsUvW
+.Op Fl efHiLlmstUvW
 .Op Fl c Ar count
 .Op Fl h Ar hashname
 .Op Fl M Ar core
@@ -126,6 +126,49 @@
 .Dv uvmexp
 structure.
 This contains various paging event and memory status counters.
+.It Fl t
+Display the contents of the
+.Dv vmtotal
+structure.
+This includes information about processes and virtual memory.
+.Pp
+The process part shows the number of processes in the following states:
+.Pp
+.Bl -tag -width abc -compact
+.It ru
+on the run queue
+.It dw
+in disk I/O wait
+.It pw
+waiting for paging
+.It sl
+sleeping while resident
+.It sw
+swapped out, but either runnable or in short-term blocking state
+.El
+.Pp
+The virtual memory section shows:
+.Pp
+.Bl -tag -width abcdefgh -compact
+.It total-v
+Total virtual memory
+.It active-v
+Active virtual memory in use
+.It active-r
+Active real memory in use
+.It vm-sh
+Shared virtual memory
+.It avm-sh
+Active shared virtual memory
+.It rm-sh
+Shared real memory
+.It arm-sh
+Active shared real memory
+.It free
+Free memory
+.El
+.Pp
+All memory values are shown in number of pages.
 .It Fl U
 Dump all UVM histories.
 .It Fl u Ar histname