changeset 13953:0cc6917308f7

3529 iostat should display time used by dtrace Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: Bryan Cantrill <bmc@joyent.com> Reviewed by: Brendan Gregg <brendan.gregg@joyent.com> Approved by: Garrett D'Amore <garrett@damore.org>
author Matthew Ahrens <mahrens@delphix.com>
date Sun, 10 Feb 2013 22:28:15 -0800
parents 7a22d0770fc8
children d0de3e428c42
files usr/src/cmd/stat/common/acquire.c usr/src/cmd/stat/common/statcommon.h usr/src/cmd/stat/iostat/iostat.c usr/src/man/man1m/iostat.1m usr/src/uts/common/dtrace/dtrace.c usr/src/uts/common/os/cpu.c usr/src/uts/common/sys/cpuvar.h
diffstat 7 files changed, 120 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/stat/common/acquire.c	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/cmd/stat/common/acquire.c	Sun Feb 10 22:28:15 2013 -0800
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include "statcommon.h"
@@ -289,6 +290,7 @@
 			return (errno);
 		if (kstat_add(&ss->s_cpus[i].cs_vm, &ss->s_sys.ss_agg_vm))
 			return (errno);
+		ss->s_nr_active_cpus++;
 	}
 
 	return (0);
--- a/usr/src/cmd/stat/common/statcommon.h	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/cmd/stat/common/statcommon.h	Sun Feb 10 22:28:15 2013 -0800
@@ -20,7 +20,10 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- *
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
  * Common routines for acquiring snapshots of kstats for
  * iostat, mpstat, and vmstat.
  */
@@ -221,6 +224,7 @@
 	size_t s_iodevs_is_name_maxlen;
 	struct sys_snapshot s_sys;
 	struct biostats s_biostats;
+	size_t s_nr_active_cpus;
 };
 
 /* print a message and exit with failure */
--- a/usr/src/cmd/stat/iostat/iostat.c	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/cmd/stat/iostat/iostat.c	Sun Feb 10 22:28:15 2013 -0800
@@ -26,6 +26,9 @@
  * rewritten from UCB 4.13 83/09/25
  * rewritten from SunOS 4.1 SID 1.18 89/10/06
  */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -422,14 +425,14 @@
  *
  * 0---------1--------2---------3---------4---------5---------6---------7-------
  *    tty        sd0           sd1           sd2           sd3           cpu
- *  tin tout kps tps serv  kps tps serv  kps tps serv  kps tps serv  us sy wt id
+ *  tin tout kps tps serv  kps tps serv  kps tps serv  kps tps serv  us sy dt id
  *  NNN NNNN NNN NNN NNNN  NNN NNN NNNN  NNN NNN NNNN  NNN NNN NNNN  NN NN NN NN
  *
  * When -D is specified, the disk header looks as follows (worst case):
  *
  * 0---------1--------2---------3---------4---------5---------6---------7-------
  *     tty        sd0           sd1             sd2          sd3          cpu
- *   tin tout rps wps util  rps wps util  rps wps util  rps wps util us sy wt id
+ *   tin tout rps wps util  rps wps util  rps wps util  rps wps util us sy dt id
  *   NNN NNNN NNN NNN NNNN  NNN NNN NNNN  NNN NNN NNNN  NNN NNN NNNN NN NN NN NN
  */
 static void
@@ -940,7 +943,7 @@
 	    "Usage: iostat [-cCdDeEiImMnpPrstxXYz] "
 	    " [-l n] [-T d|u] [disk ...] [interval [count]]\n"
 	    "\t\t-c: 	report percentage of time system has spent\n"
-	    "\t\t\tin user/system/wait/idle mode\n"
+	    "\t\t\tin user/system/dtrace/idle mode\n"
 	    "\t\t-C: 	report disk statistics by controller\n"
 	    "\t\t-d: 	display disk Kb/sec, transfers/sec, avg. \n"
 	    "\t\t\tservice time in milliseconds  \n"
@@ -1489,9 +1492,9 @@
 	char *dstr;
 
 	if (do_raw == 0)
-		dstr = " us sy wt id";
+		dstr = " us sy dt id";
 	else
-		dstr = "us,sy,wt,id";
+		dstr = "us,sy,dt,id";
 	push_out(dstr);
 }
 
@@ -1534,7 +1537,8 @@
 	uint64_t idle;
 	uint64_t user;
 	uint64_t kern;
-	uint64_t wait;
+	uint64_t dtrace;
+	uint64_t nsec_elapsed;
 	kstat_t *oldks = NULL;
 
 	if (oldss)
@@ -1548,9 +1552,13 @@
 	idle = kstat_delta(oldks, &newss->s_sys.ss_agg_sys, "cpu_ticks_idle");
 	user = kstat_delta(oldks, &newss->s_sys.ss_agg_sys, "cpu_ticks_user");
 	kern = kstat_delta(oldks, &newss->s_sys.ss_agg_sys, "cpu_ticks_kernel");
-	wait = kstat_delta(oldks, &newss->s_sys.ss_agg_sys, "cpu_ticks_wait");
+	dtrace = kstat_delta(oldks, &newss->s_sys.ss_agg_sys,
+	    "cpu_nsec_dtrace");
+	nsec_elapsed = newss->s_sys.ss_agg_sys.ks_snaptime -
+	    (oldks == NULL ? 0 : oldks->ks_snaptime);
 	push_out(fstr, user * percent, kern * percent,
-	    wait * percent, idle * percent);
+	    dtrace * 100.0 / nsec_elapsed / newss->s_nr_active_cpus,
+	    idle * percent);
 }
 
 /*
--- a/usr/src/man/man1m/iostat.1m	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/man/man1m/iostat.1m	Sun Feb 10 22:28:15 2013 -0800
@@ -1,8 +1,27 @@
 '\" te
+.\"
+.\" CDDL HEADER START
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" CDDL HEADER END
+.\"
 .\" Copyright (c) 2003, Sun Microsystems, Inc.  All Rights reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
-.\"  See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with
-.\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
+.\" Copyright (c) 2012 by Delphix. All rights reserved.
+.\"
 .TH IOSTAT 1M "Mar 23, 2009"
 .SH NAME
 iostat \- report I/O statistics
@@ -194,16 +213,6 @@
 average service time of active transactions, in milliseconds
 .RE
 
-.sp
-.ne 2
-.na
-\fB\fBwt\fR\fR
-.ad
-.RS 10n
-the I/O wait time is no longer calculated as a percentage of \fBCPU\fR time,
-and this statistic will always return zero.
-.RE
-
 .SH OPTIONS
 .sp
 .LP
@@ -215,8 +224,8 @@
 .ad
 .RS 12n
 Report the percentage of time the system has spent in user mode, in system
-mode, waiting for \fBI/O,\fR and idling. See the NOTES section for more
-information.
+mode, in dtrace probes, and idling. See the NOTES section and
+\fBmpstat\fR(1m) for more information.
 .RE
 
 .sp
@@ -510,7 +519,7 @@
 
 Mon Nov 24 14:58:36 2003
     cpu
- us sy wt id
+ us sy dt id
  14 31  0 20
                     extended device statistics
   r/s    w/s    kr/s      kw wait  actv wsvc_t asvc_t  %w  %b device
@@ -520,8 +529,8 @@
 
 Mon Nov 24 14:58:41 2003
     cpu
- us sy wt id
- 11 31  0 22
+ us sy dt id
+ 11 31  1 22
                     extended device statistics
   r/s    w/s    kr/s      kw wait  actv wsvc_t asvc_t  %w  %b device
   0.8   41.0     5.2    20.5 0.0    0.2    0.2    4.4   0   6     c0
@@ -546,14 +555,14 @@
 
 
                   extended device statistics        tty         cpu
-device r/s  w/s kr/s  kw/s wait actv svc_t %w  %b  tin tout  us sy wt id
+device r/s  w/s kr/s  kw/s wait actv svc_t %w  %b  tin tout  us sy dt id
 sd0    0.4  0.3 10.4   8.0  0.0  0.0  36.9  0   1    0   10   0  0  0 99
 sd1    0.0  0.0  0.3   0.4  0.0  0.0  35.0  0   0
 sd6    0.0  0.0  0.0   0.0  0.0  0.0   0.0  0   0
 nfs1   0.0  0.0  0.0   0.0  0.0  0.0   0.0  0   0
 nfs2   0.0  0.0  0.0   0.1  0.0  0.0  35.6  0   0
             extended device statistics              tty         cpu
-device r/s  w/s  kr/s  kw/s wait actv svc_t %w  %b tin tout  us sy wt id
+device r/s  w/s  kr/s  kw/s wait actv svc_t %w  %b tin tout  us sy dt id
 sd0    0.0  0.0  0.0   0.0  0.0  0.0  0.0   0   0   0  155   0  0  0 100
 sd1    0.0  0.0  0.0   0.0  0.0  0.0  0.0   0   0
 sd6    0.0  0.0  0.0   0.0  0.0  0.0  0.0   0   0
@@ -664,7 +673,7 @@
 are fairly normal in such cases.
 .sp
 .LP
-The \fBmpstat\fR utility reports the same \fBwt\fR, \fBusr\fR, and \fBsys\fR
+The \fBmpstat\fR utility reports the same \fBdt\fR, \fBusr\fR, and \fBsys\fR
 statistics. See \fBmpstat\fR(1M) for more information.
 .sp
 .LP
--- a/usr/src/uts/common/dtrace/dtrace.c	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/uts/common/dtrace/dtrace.c	Sun Feb 10 22:28:15 2013 -0800
@@ -5861,7 +5861,7 @@
 	size_t size;
 	int vtime, onintr;
 	volatile uint16_t *flags;
-	hrtime_t now;
+	hrtime_t now, end;
 
 	/*
 	 * Kick out immediately if this CPU is still being born (in which case
@@ -5876,6 +5876,8 @@
 	cpuid = CPU->cpu_id;
 	onintr = CPU_ON_INTR(CPU);
 
+	CPU->cpu_dtrace_probes++;
+
 	if (!onintr && probe->dtpr_predcache != DTRACE_CACHEIDNONE &&
 	    probe->dtpr_predcache == curthread->t_predcache) {
 		/*
@@ -6455,8 +6457,11 @@
 			buf->dtb_offset = offs + ecb->dte_size;
 	}
 
+	end = dtrace_gethrtime();
 	if (vtime)
-		curthread->t_dtrace_start = dtrace_gethrtime();
+		curthread->t_dtrace_start = end;
+
+	CPU->cpu_dtrace_nsec += end - now;
 
 	dtrace_interrupt_enable(cookie);
 }
--- a/usr/src/uts/common/os/cpu.c	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/uts/common/os/cpu.c	Sun Feb 10 22:28:15 2013 -0800
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 /*
@@ -182,9 +183,11 @@
 	kstat_named_t cpu_nsec_idle;
 	kstat_named_t cpu_nsec_user;
 	kstat_named_t cpu_nsec_kernel;
+	kstat_named_t cpu_nsec_dtrace;
 	kstat_named_t cpu_nsec_intr;
 	kstat_named_t cpu_load_intr;
 	kstat_named_t wait_ticks_io;
+	kstat_named_t dtrace_probes;
 	kstat_named_t bread;
 	kstat_named_t bwrite;
 	kstat_named_t lread;
@@ -232,61 +235,63 @@
 	kstat_named_t bawrite;
 	kstat_named_t iowait;
 } cpu_sys_stats_ks_data_template = {
-	{ "cpu_ticks_idle", 	KSTAT_DATA_UINT64 },
-	{ "cpu_ticks_user", 	KSTAT_DATA_UINT64 },
-	{ "cpu_ticks_kernel", 	KSTAT_DATA_UINT64 },
-	{ "cpu_ticks_wait", 	KSTAT_DATA_UINT64 },
+	{ "cpu_ticks_idle",	KSTAT_DATA_UINT64 },
+	{ "cpu_ticks_user",	KSTAT_DATA_UINT64 },
+	{ "cpu_ticks_kernel",	KSTAT_DATA_UINT64 },
+	{ "cpu_ticks_wait",	KSTAT_DATA_UINT64 },
 	{ "cpu_nsec_idle",	KSTAT_DATA_UINT64 },
 	{ "cpu_nsec_user",	KSTAT_DATA_UINT64 },
 	{ "cpu_nsec_kernel",	KSTAT_DATA_UINT64 },
+	{ "cpu_nsec_dtrace",	KSTAT_DATA_UINT64 },
 	{ "cpu_nsec_intr",	KSTAT_DATA_UINT64 },
 	{ "cpu_load_intr",	KSTAT_DATA_UINT64 },
-	{ "wait_ticks_io", 	KSTAT_DATA_UINT64 },
-	{ "bread", 		KSTAT_DATA_UINT64 },
-	{ "bwrite", 		KSTAT_DATA_UINT64 },
-	{ "lread", 		KSTAT_DATA_UINT64 },
-	{ "lwrite", 		KSTAT_DATA_UINT64 },
-	{ "phread", 		KSTAT_DATA_UINT64 },
-	{ "phwrite", 		KSTAT_DATA_UINT64 },
-	{ "pswitch", 		KSTAT_DATA_UINT64 },
-	{ "trap", 		KSTAT_DATA_UINT64 },
-	{ "intr", 		KSTAT_DATA_UINT64 },
-	{ "syscall", 		KSTAT_DATA_UINT64 },
-	{ "sysread", 		KSTAT_DATA_UINT64 },
-	{ "syswrite", 		KSTAT_DATA_UINT64 },
-	{ "sysfork", 		KSTAT_DATA_UINT64 },
-	{ "sysvfork", 		KSTAT_DATA_UINT64 },
-	{ "sysexec", 		KSTAT_DATA_UINT64 },
-	{ "readch", 		KSTAT_DATA_UINT64 },
-	{ "writech", 		KSTAT_DATA_UINT64 },
-	{ "rcvint", 		KSTAT_DATA_UINT64 },
-	{ "xmtint", 		KSTAT_DATA_UINT64 },
-	{ "mdmint", 		KSTAT_DATA_UINT64 },
-	{ "rawch", 		KSTAT_DATA_UINT64 },
-	{ "canch", 		KSTAT_DATA_UINT64 },
-	{ "outch", 		KSTAT_DATA_UINT64 },
-	{ "msg", 		KSTAT_DATA_UINT64 },
-	{ "sema", 		KSTAT_DATA_UINT64 },
-	{ "namei", 		KSTAT_DATA_UINT64 },
-	{ "ufsiget", 		KSTAT_DATA_UINT64 },
-	{ "ufsdirblk", 		KSTAT_DATA_UINT64 },
-	{ "ufsipage", 		KSTAT_DATA_UINT64 },
-	{ "ufsinopage", 	KSTAT_DATA_UINT64 },
-	{ "procovf", 		KSTAT_DATA_UINT64 },
-	{ "intrthread", 	KSTAT_DATA_UINT64 },
-	{ "intrblk", 		KSTAT_DATA_UINT64 },
+	{ "wait_ticks_io",	KSTAT_DATA_UINT64 },
+	{ "dtrace_probes",	KSTAT_DATA_UINT64 },
+	{ "bread",		KSTAT_DATA_UINT64 },
+	{ "bwrite",		KSTAT_DATA_UINT64 },
+	{ "lread",		KSTAT_DATA_UINT64 },
+	{ "lwrite",		KSTAT_DATA_UINT64 },
+	{ "phread",		KSTAT_DATA_UINT64 },
+	{ "phwrite",		KSTAT_DATA_UINT64 },
+	{ "pswitch",		KSTAT_DATA_UINT64 },
+	{ "trap",		KSTAT_DATA_UINT64 },
+	{ "intr",		KSTAT_DATA_UINT64 },
+	{ "syscall",		KSTAT_DATA_UINT64 },
+	{ "sysread",		KSTAT_DATA_UINT64 },
+	{ "syswrite",		KSTAT_DATA_UINT64 },
+	{ "sysfork",		KSTAT_DATA_UINT64 },
+	{ "sysvfork",		KSTAT_DATA_UINT64 },
+	{ "sysexec",		KSTAT_DATA_UINT64 },
+	{ "readch",		KSTAT_DATA_UINT64 },
+	{ "writech",		KSTAT_DATA_UINT64 },
+	{ "rcvint",		KSTAT_DATA_UINT64 },
+	{ "xmtint",		KSTAT_DATA_UINT64 },
+	{ "mdmint",		KSTAT_DATA_UINT64 },
+	{ "rawch",		KSTAT_DATA_UINT64 },
+	{ "canch",		KSTAT_DATA_UINT64 },
+	{ "outch",		KSTAT_DATA_UINT64 },
+	{ "msg",		KSTAT_DATA_UINT64 },
+	{ "sema",		KSTAT_DATA_UINT64 },
+	{ "namei",		KSTAT_DATA_UINT64 },
+	{ "ufsiget",		KSTAT_DATA_UINT64 },
+	{ "ufsdirblk",		KSTAT_DATA_UINT64 },
+	{ "ufsipage",		KSTAT_DATA_UINT64 },
+	{ "ufsinopage",		KSTAT_DATA_UINT64 },
+	{ "procovf",		KSTAT_DATA_UINT64 },
+	{ "intrthread",		KSTAT_DATA_UINT64 },
+	{ "intrblk",		KSTAT_DATA_UINT64 },
 	{ "intrunpin",		KSTAT_DATA_UINT64 },
-	{ "idlethread", 	KSTAT_DATA_UINT64 },
-	{ "inv_swtch", 		KSTAT_DATA_UINT64 },
-	{ "nthreads", 		KSTAT_DATA_UINT64 },
-	{ "cpumigrate", 	KSTAT_DATA_UINT64 },
-	{ "xcalls", 		KSTAT_DATA_UINT64 },
-	{ "mutex_adenters", 	KSTAT_DATA_UINT64 },
-	{ "rw_rdfails", 	KSTAT_DATA_UINT64 },
-	{ "rw_wrfails", 	KSTAT_DATA_UINT64 },
-	{ "modload", 		KSTAT_DATA_UINT64 },
-	{ "modunload", 		KSTAT_DATA_UINT64 },
-	{ "bawrite", 		KSTAT_DATA_UINT64 },
+	{ "idlethread",		KSTAT_DATA_UINT64 },
+	{ "inv_swtch",		KSTAT_DATA_UINT64 },
+	{ "nthreads",		KSTAT_DATA_UINT64 },
+	{ "cpumigrate",		KSTAT_DATA_UINT64 },
+	{ "xcalls",		KSTAT_DATA_UINT64 },
+	{ "mutex_adenters",	KSTAT_DATA_UINT64 },
+	{ "rw_rdfails",		KSTAT_DATA_UINT64 },
+	{ "rw_wrfails",		KSTAT_DATA_UINT64 },
+	{ "modload",		KSTAT_DATA_UINT64 },
+	{ "modunload",		KSTAT_DATA_UINT64 },
+	{ "bawrite",		KSTAT_DATA_UINT64 },
 	{ "iowait",		KSTAT_DATA_UINT64 },
 };
 
@@ -3206,6 +3211,8 @@
 	    NSEC_TO_TICK(csskd->cpu_nsec_user.value.ui64);
 	csskd->cpu_ticks_kernel.value.ui64 =
 	    NSEC_TO_TICK(csskd->cpu_nsec_kernel.value.ui64);
+	csskd->cpu_nsec_dtrace.value.ui64 = cp->cpu_dtrace_nsec;
+	csskd->dtrace_probes.value.ui64 = cp->cpu_dtrace_probes;
 	csskd->cpu_nsec_intr.value.ui64 = cp->cpu_intrlast;
 	csskd->cpu_load_intr.value.ui64 = cp->cpu_intrload;
 	csskd->bread.value.ui64 = css->bread;
--- a/usr/src/uts/common/sys/cpuvar.h	Sun Feb 10 22:21:05 2013 -0800
+++ b/usr/src/uts/common/sys/cpuvar.h	Sun Feb 10 22:28:15 2013 -0800
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_CPUVAR_H
@@ -187,6 +188,9 @@
 	uintptr_t	cpu_dtrace_caller;	/* DTrace: caller, if any */
 	hrtime_t	cpu_dtrace_chillmark;	/* DTrace: chill mark time */
 	hrtime_t	cpu_dtrace_chilled;	/* DTrace: total chill time */
+	uint64_t	cpu_dtrace_probes;	/* DTrace: total probes fired */
+	hrtime_t	cpu_dtrace_nsec;	/* DTrace: ns in dtrace_probe */
+
 	volatile uint16_t cpu_mstate;		/* cpu microstate */
 	volatile uint16_t cpu_mstate_gen;	/* generation counter */
 	volatile hrtime_t cpu_mstate_start;	/* cpu microstate start time */