1235368Sgnn#!/usr/sbin/dtrace -s
2235368Sgnn/*
3235368Sgnn * vmstat.d - vmstat demo in DTrace.
4235368Sgnn *            Written using DTrace (Solaris 10 3/05).
5235368Sgnn *
6235368Sgnn * This has been written to demonstrate fetching the same data as vmstat
7235368Sgnn * from DTrace. This program is intended as a starting point for other
8235368Sgnn * DTrace scripts, by beginning with familiar statistics.
9235368Sgnn *
10235368Sgnn * $Id: vmstat.d 8 2007-08-06 05:55:26Z brendan $
11235368Sgnn *
12235368Sgnn * USAGE:	vmstat.d
13235368Sgnn *
14235368Sgnn * FIELDS:
15235368Sgnn *		w	swapped out LWPs	number
16235368Sgnn *		swap	virtual memory free	Kbytes
17235368Sgnn *		free	free RAM		Kbytes
18235368Sgnn *		re	page reclaims		Kbytes
19235368Sgnn *		mf	minor faults		Kbytes
20235368Sgnn *		pi	page ins		Kbytes
21235368Sgnn *		po	page outs		Kbytes
22235368Sgnn *		fr	pages freed		Kbytes
23235368Sgnn *		sr	scan rate		pages
24235368Sgnn *		in	interrupts		number
25235368Sgnn *		sy	system calls		number
26235368Sgnn *		cs	context switches	number
27235368Sgnn *
28235368Sgnn * NOTES:
29235368Sgnn *  Most of the statistics are in units of kilobytes, unlike the
30235368Sgnn *  original vmstat command which sometimes uses page counts.
31235368Sgnn *  As this program does not use Kstat, there is no summary since boot line.
32235368Sgnn *  Free RAM is both free free + cache free.
33235368Sgnn *
34235368Sgnn * SEE ALSO:	vmstat(1M)
35235368Sgnn *
36235368Sgnn * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
37235368Sgnn *
38235368Sgnn * CDDL HEADER START
39235368Sgnn *
40235368Sgnn *  The contents of this file are subject to the terms of the
41235368Sgnn *  Common Development and Distribution License, Version 1.0 only
42235368Sgnn *  (the "License").  You may not use this file except in compliance
43235368Sgnn *  with the License.
44235368Sgnn *
45235368Sgnn *  You can obtain a copy of the license at Docs/cddl1.txt
46235368Sgnn *  or http://www.opensolaris.org/os/licensing.
47235368Sgnn *  See the License for the specific language governing permissions
48235368Sgnn *  and limitations under the License.
49235368Sgnn *
50235368Sgnn * CDDL HEADER END
51235368Sgnn *
52235368Sgnn * 11-Jun-2005  Brendan Gregg   Created this.
53235368Sgnn * 08-Jan-2006	   "      "	Last update.
54235368Sgnn */
55235368Sgnn
56235368Sgnn#pragma D option quiet
57235368Sgnn
58235368Sgnninline int SCREEN = 21;
59235368Sgnn
60235368Sgnn/*
61235368Sgnn * Initialise variables
62235368Sgnn */
63235368Sgnndtrace:::BEGIN
64235368Sgnn{
65235368Sgnn	pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
66235368Sgnn	sy = 0; in = 0; cs = 0;
67235368Sgnn	lines = SCREEN + 1;
68235368Sgnn}
69235368Sgnn
70235368Sgnn/*
71235368Sgnn * Print header
72235368Sgnn */
73235368Sgnndtrace:::BEGIN,
74235368Sgnnprofile:::tick-1sec
75235368Sgnn/lines++ > SCREEN/
76235368Sgnn{
77235368Sgnn	printf(" %1s %10s %8s %5s %5s %4s %4s %4s %4s %5s %6s %4s\n",
78235368Sgnn	    "w", "swap", "free", "re", "mf", "pi", "po", "fr", "sr",
79235368Sgnn	    "in", "sy", "cs");
80235368Sgnn	lines = 0;
81235368Sgnn}
82235368Sgnn
83235368Sgnn/*
84235368Sgnn * Probe events
85235368Sgnn */
86235368Sgnnvminfo:::pgpgin   { pi += arg0; }
87235368Sgnnvminfo:::pgpgout  { po += arg0; }
88235368Sgnnvminfo:::pgrec    { re += arg0; }
89235368Sgnnvminfo:::scan	  { sr += arg0; }
90235368Sgnnvminfo:::as_fault { mf += arg0; }
91235368Sgnnvminfo:::dfree    { fr += arg0; }
92235368Sgnn
93235368Sgnnsyscall:::entry		{ sy++; }
94235368Sgnnsdt:::interrupt-start	{ in++; }
95235368Sgnnsched::resume:on-cpu	{ cs++; }
96235368Sgnn
97235368Sgnn/*
98235368Sgnn * Print output line
99235368Sgnn */
100235368Sgnnprofile:::tick-1sec
101235368Sgnn{
102235368Sgnn	/* fetch free mem */
103235368Sgnn	this->free = `freemem;
104235368Sgnn
105235368Sgnn	/*
106235368Sgnn	 * fetch free swap
107235368Sgnn	 *
108235368Sgnn	 * free swap is described in /usr/include/vm/anon.h as,
109235368Sgnn	 * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
110235368Sgnn	 */
111235368Sgnn	this->ani_max = `k_anoninfo.ani_max;
112235368Sgnn	this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv;
113235368Sgnn	this->swap = (this->ani_max - this->ani_resv > 0 ?
114235368Sgnn	    this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree;
115235368Sgnn
116235368Sgnn	/* fetch w */
117235368Sgnn	this->w = `nswapped;
118235368Sgnn
119235368Sgnn	/* convert to Kbytes */
120235368Sgnn	pi *= `_pagesize / 1024;
121235368Sgnn	po *= `_pagesize / 1024;
122235368Sgnn	re *= `_pagesize / 1024;
123235368Sgnn	sr *= `_pagesize / 1024;
124235368Sgnn	mf *= `_pagesize / 1024;
125235368Sgnn	fr *= `_pagesize / 1024;
126235368Sgnn	this->swap *= `_pagesize / 1024;
127235368Sgnn	this->free *= `_pagesize / 1024;
128235368Sgnn
129235368Sgnn	/* print line */
130235368Sgnn	printf(" %1d %10d %8d %5d %5d %4d %4d %4d %4d %5d %6d %4d\n",
131235368Sgnn	    this->w, this->swap, this->free, re, mf, pi, po, fr, sr,
132235368Sgnn	    in, sy, cs);
133235368Sgnn
134235368Sgnn	/* clear counters */
135235368Sgnn	pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
136235368Sgnn	sy = 0; in = 0; cs = 0;
137235368Sgnn}
138