15184Sek110237 /* 25184Sek110237 * CDDL HEADER START 35184Sek110237 * 45184Sek110237 * The contents of this file are subject to the terms of the 55184Sek110237 * Common Development and Distribution License (the "License"). 65184Sek110237 * You may not use this file except in compliance with the License. 75184Sek110237 * 85184Sek110237 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95184Sek110237 * or http://www.opensolaris.org/os/licensing. 105184Sek110237 * See the License for the specific language governing permissions 115184Sek110237 * and limitations under the License. 125184Sek110237 * 135184Sek110237 * When distributing Covered Code, include this CDDL HEADER in each 145184Sek110237 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155184Sek110237 * If applicable, add the following below this CDDL HEADER, with the 165184Sek110237 * fields enclosed by brackets "[]" replaced with your own identifying 175184Sek110237 * information: Portions Copyright [yyyy] [name of copyright owner] 185184Sek110237 * 195184Sek110237 * CDDL HEADER END 205184Sek110237 */ 215184Sek110237 /* 22*9356SAndrew.W.Wilson@sun.com * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235184Sek110237 * Use is subject to license terms. 245184Sek110237 */ 255184Sek110237 265184Sek110237 #include "config.h" 275184Sek110237 285184Sek110237 #include <stdio.h> 295184Sek110237 #include <fcntl.h> 305184Sek110237 #include <sys/types.h> 315184Sek110237 325184Sek110237 #ifdef HAVE_SYSINFO 335184Sek110237 #include <sys/sysinfo.h> 345184Sek110237 #endif 355184Sek110237 365184Sek110237 #ifdef HAVE_LIBKSTAT 375184Sek110237 #include <kstat.h> 385184Sek110237 #include <sys/cpuvar.h> 395184Sek110237 #endif /* HAVE_LIBKSTAT */ 405184Sek110237 415184Sek110237 #include <stdarg.h> 425184Sek110237 435184Sek110237 #include "filebench.h" 445184Sek110237 #include "flowop.h" 455184Sek110237 #include "vars.h" 465184Sek110237 #include "stats.h" 475184Sek110237 485184Sek110237 /* 495184Sek110237 * A set of routines for collecting and dumping various filebench 505184Sek110237 * run statistics. 515184Sek110237 */ 525184Sek110237 535184Sek110237 /* Global statistics */ 545184Sek110237 static flowstat_t *globalstats = NULL; 555184Sek110237 565184Sek110237 static hrtime_t stats_cputime = 0; 575184Sek110237 585184Sek110237 #ifdef HAVE_LIBKSTAT 595184Sek110237 static kstat_ctl_t *kstatp = NULL; 605184Sek110237 static kstat_t *sysinfo_ksp = NULL; 61*9356SAndrew.W.Wilson@sun.com static kstat_t **cpu_kstat_list = NULL; 62*9356SAndrew.W.Wilson@sun.com static int kstat_ncpus = 0; 63*9356SAndrew.W.Wilson@sun.com 64*9356SAndrew.W.Wilson@sun.com static int 65*9356SAndrew.W.Wilson@sun.com stats_build_kstat_list(void) 66*9356SAndrew.W.Wilson@sun.com { 67*9356SAndrew.W.Wilson@sun.com kstat_t *ksp; 68*9356SAndrew.W.Wilson@sun.com 69*9356SAndrew.W.Wilson@sun.com kstat_ncpus = 0; 70*9356SAndrew.W.Wilson@sun.com for (ksp = kstatp->kc_chain; ksp; ksp = ksp->ks_next) 71*9356SAndrew.W.Wilson@sun.com if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0) 72*9356SAndrew.W.Wilson@sun.com kstat_ncpus++; 73*9356SAndrew.W.Wilson@sun.com 74*9356SAndrew.W.Wilson@sun.com if ((cpu_kstat_list = (kstat_t **) 75*9356SAndrew.W.Wilson@sun.com malloc(kstat_ncpus * sizeof (kstat_t *))) == NULL) { 76*9356SAndrew.W.Wilson@sun.com filebench_log(LOG_ERROR, "malloc failed"); 77*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_ERROR); 78*9356SAndrew.W.Wilson@sun.com } 79*9356SAndrew.W.Wilson@sun.com 80*9356SAndrew.W.Wilson@sun.com kstat_ncpus = 0; 81*9356SAndrew.W.Wilson@sun.com for (ksp = kstatp->kc_chain; ksp; ksp = ksp->ks_next) 82*9356SAndrew.W.Wilson@sun.com if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0 && 83*9356SAndrew.W.Wilson@sun.com kstat_read(kstatp, ksp, NULL) != -1) 84*9356SAndrew.W.Wilson@sun.com cpu_kstat_list[kstat_ncpus++] = ksp; 85*9356SAndrew.W.Wilson@sun.com 86*9356SAndrew.W.Wilson@sun.com if (kstat_ncpus == 0) { 87*9356SAndrew.W.Wilson@sun.com filebench_log(LOG_ERROR, 88*9356SAndrew.W.Wilson@sun.com "kstats can't find any cpu statistics"); 89*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_ERROR); 90*9356SAndrew.W.Wilson@sun.com } 91*9356SAndrew.W.Wilson@sun.com 92*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_OK); 93*9356SAndrew.W.Wilson@sun.com } 94*9356SAndrew.W.Wilson@sun.com 95*9356SAndrew.W.Wilson@sun.com static int 96*9356SAndrew.W.Wilson@sun.com stats_kstat_update(void) 97*9356SAndrew.W.Wilson@sun.com { 98*9356SAndrew.W.Wilson@sun.com if (kstatp == NULL) { 99*9356SAndrew.W.Wilson@sun.com if ((kstatp = kstat_open()) == (kstat_ctl_t *)NULL) { 100*9356SAndrew.W.Wilson@sun.com filebench_log(LOG_ERROR, "Cannot read kstats"); 101*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_ERROR); 102*9356SAndrew.W.Wilson@sun.com } 103*9356SAndrew.W.Wilson@sun.com } 104*9356SAndrew.W.Wilson@sun.com 105*9356SAndrew.W.Wilson@sun.com /* get the sysinfo kstat */ 106*9356SAndrew.W.Wilson@sun.com if (sysinfo_ksp == NULL) 107*9356SAndrew.W.Wilson@sun.com sysinfo_ksp = kstat_lookup(kstatp, "unix", 0, "sysinfo"); 108*9356SAndrew.W.Wilson@sun.com 109*9356SAndrew.W.Wilson@sun.com /* get per cpu kstats, if necessary */ 110*9356SAndrew.W.Wilson@sun.com if (cpu_kstat_list == NULL) { 111*9356SAndrew.W.Wilson@sun.com 112*9356SAndrew.W.Wilson@sun.com /* Initialize the array of cpu kstat pointers */ 113*9356SAndrew.W.Wilson@sun.com if (stats_build_kstat_list() == FILEBENCH_ERROR) 114*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_ERROR); 115*9356SAndrew.W.Wilson@sun.com 116*9356SAndrew.W.Wilson@sun.com } else if (kstat_chain_update(kstatp) != 0) { 117*9356SAndrew.W.Wilson@sun.com 118*9356SAndrew.W.Wilson@sun.com /* free up current array of kstat ptrs and get new one */ 119*9356SAndrew.W.Wilson@sun.com free((void *)cpu_kstat_list); 120*9356SAndrew.W.Wilson@sun.com if (stats_build_kstat_list() == FILEBENCH_ERROR) 121*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_ERROR); 122*9356SAndrew.W.Wilson@sun.com } 123*9356SAndrew.W.Wilson@sun.com 124*9356SAndrew.W.Wilson@sun.com return (FILEBENCH_OK); 125*9356SAndrew.W.Wilson@sun.com } 1265184Sek110237 1275184Sek110237 /* 1285184Sek110237 * Uses the kstat library or, if it is not available, the /proc/stat file 1295184Sek110237 * to obtain cpu statistics. Collects statistics for each cpu, initializes 1305184Sek110237 * a local pointer to the sysinfo kstat, and returns the sum of user and 1315184Sek110237 * kernel time for all the cpus. 1325184Sek110237 */ 1336212Saw148015 static fbint_t 1345184Sek110237 kstats_read_cpu(void) 1355184Sek110237 { 1365184Sek110237 ulong_t cputime_states[CPU_STATES]; 1375184Sek110237 hrtime_t cputime; 1385184Sek110237 int i; 1395184Sek110237 1405184Sek110237 /* 1415184Sek110237 * Per-CPU statistics 1425184Sek110237 */ 1435184Sek110237 144*9356SAndrew.W.Wilson@sun.com if (stats_kstat_update() == FILEBENCH_ERROR) 1455184Sek110237 return (0); 1465184Sek110237 1475184Sek110237 /* Sum across all CPUs */ 1485184Sek110237 (void) memset(&cputime_states, 0, sizeof (cputime_states)); 149*9356SAndrew.W.Wilson@sun.com for (i = 0; i < kstat_ncpus; i++) { 1505184Sek110237 cpu_stat_t cpu_stats; 1515184Sek110237 int j; 1525184Sek110237 153*9356SAndrew.W.Wilson@sun.com (void) kstat_read(kstatp, cpu_kstat_list[i], 1545184Sek110237 (void *) &cpu_stats); 1555184Sek110237 for (j = 0; j < CPU_STATES; j++) 1565184Sek110237 cputime_states[j] += cpu_stats.cpu_sysinfo.cpu[j]; 1575184Sek110237 } 1585184Sek110237 1595184Sek110237 cputime = cputime_states[CPU_KERNEL] + cputime_states[CPU_USER]; 1605184Sek110237 1615184Sek110237 return (10000000LL * cputime); 1625184Sek110237 } 1635184Sek110237 #else /* HAVE_LIBKSTAT */ 1645184Sek110237 #ifdef HAVE_PROC_STAT 1655184Sek110237 static FILE *statfd = 0; 1666212Saw148015 fbint_t 1675184Sek110237 kstats_read_cpu(void) 1685184Sek110237 { 1695184Sek110237 /* 1705184Sek110237 * Linux provides system wide statistics in /proc/stat 1715184Sek110237 * The entry for cpu is 1725184Sek110237 * cpu 1636 67 1392 208671 5407 20 12 1735184Sek110237 * cpu0 626 8 997 104476 2499 7 7 1745184Sek110237 * cpu1 1010 58 395 104195 2907 13 5 1755184Sek110237 * 1765184Sek110237 * The number of jiffies (1/100ths of a second) that the 1775184Sek110237 * system spent in user mode, user mode with low priority 1785184Sek110237 * (nice), system mode, and the idle task, respectively. 1795184Sek110237 */ 1805184Sek110237 unsigned int user, nice, system; 1815184Sek110237 char cpu[128]; /* placeholder to read "cpu" */ 1825184Sek110237 if (statfd == 0) { 1835184Sek110237 statfd = fopen("/proc/stat", "r"); 1845184Sek110237 if (statfd < 0) { 1855184Sek110237 filebench_log(LOG_ERROR, "Cannot open /proc/stat"); 1865184Sek110237 return (-1); 1875184Sek110237 } 1885184Sek110237 } 1895184Sek110237 if (fscanf(statfd, "%s %u %u %u", cpu, &user, &nice, &system) < 0) { 1905184Sek110237 filebench_log(LOG_ERROR, "Cannot read /proc/stat"); 1915184Sek110237 return (-1); 1925184Sek110237 } 1935184Sek110237 /* convert jiffies to nanosecs */ 1945184Sek110237 return ((user+nice+system)*1000000); 1955184Sek110237 } 1965184Sek110237 1975184Sek110237 #else /* HAVE_PROC_STAT */ 1986212Saw148015 fbint_t 1995184Sek110237 kstats_read_cpu(void) 2005184Sek110237 { 2015184Sek110237 return (0); 2025184Sek110237 } 2035184Sek110237 #endif 2045184Sek110237 #endif /* HAVE_LIBKSTAT */ 2055184Sek110237 2065184Sek110237 /* 2075184Sek110237 * Returns the net cpu time used since the beginning of the run. 2085184Sek110237 * Just calls kstat_read_cpu() and subtracts stats_cputime which 2095184Sek110237 * is set at the beginning of the filebench run. 2105184Sek110237 */ 2115184Sek110237 static hrtime_t 2125184Sek110237 kstats_read_cpu_relative(void) 2135184Sek110237 { 2145184Sek110237 hrtime_t cputime; 2155184Sek110237 2165184Sek110237 cputime = kstats_read_cpu(); 2175184Sek110237 return (cputime - stats_cputime); 2185184Sek110237 } 2195184Sek110237 2205184Sek110237 /* 2215184Sek110237 * IO Overhead CPU is the amount of CPU that is incurred running 2225184Sek110237 * the benchmark infrastructure. 2235184Sek110237 * 2245184Sek110237 * It is computed as the sum of micro-state cpu time for each 2255184Sek110237 * thread around the op being tested. 2265184Sek110237 * 2275184Sek110237 * Overhead time is computed for each flow. 2285184Sek110237 * 2295184Sek110237 * System overhead is computed as the overhead for I/O flows 2305184Sek110237 * plus all other time running non-io related flowops 2315184Sek110237 * 2325184Sek110237 */ 2335184Sek110237 2345184Sek110237 /* 2355184Sek110237 * Computes and returns the overhead CPU time attibutable to 2365184Sek110237 * IO type flowops. 2375184Sek110237 */ 2385184Sek110237 static hrtime_t 2395184Sek110237 io_stats_ohead(void) 2405184Sek110237 { 2415184Sek110237 flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 2425184Sek110237 flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 2435184Sek110237 flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL]; 2445184Sek110237 2455184Sek110237 filebench_log(LOG_DEBUG_NEVER, 2466286Saw148015 "Computing overhead as %llu + %llu - %llu - %llu", 2476286Saw148015 (u_longlong_t)glstat->fs_mstate[FLOW_MSTATE_OHEAD], 2486286Saw148015 (u_longlong_t)glstat->fs_mstate[FLOW_MSTATE_CPU], 2496286Saw148015 (u_longlong_t)iostat->fs_mstate[FLOW_MSTATE_CPU], 2506286Saw148015 (u_longlong_t)aiostat->fs_mstate[FLOW_MSTATE_CPU]); 2515184Sek110237 2525184Sek110237 return ((glstat->fs_mstate[FLOW_MSTATE_OHEAD] + 2535184Sek110237 glstat->fs_mstate[FLOW_MSTATE_CPU] - 2545184Sek110237 iostat->fs_mstate[FLOW_MSTATE_CPU] - 2555184Sek110237 aiostat->fs_mstate[FLOW_MSTATE_CPU])); 2565184Sek110237 } 2575184Sek110237 2585184Sek110237 /* 2595184Sek110237 * Returns the total overhead CPU time. 2605184Sek110237 */ 2615184Sek110237 static hrtime_t 2625184Sek110237 gl_stats_ohead(void) 2635184Sek110237 { 2645184Sek110237 flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL]; 2655184Sek110237 2665184Sek110237 return (glstat->fs_mstate[FLOW_MSTATE_OHEAD]); 2675184Sek110237 } 2685184Sek110237 2695184Sek110237 /* 2706212Saw148015 * Places the value represented by "name" into the var_val.integer field of the 2715184Sek110237 * supplied var_t. Compares the supplied "name" with a set of predefined 2725184Sek110237 * names and calculates the value from the appropriate globalstats field(s). 2735184Sek110237 */ 2745184Sek110237 var_t * 2755184Sek110237 stats_findvar(var_t *var, char *name) 2765184Sek110237 { 2775184Sek110237 flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 2785184Sek110237 flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 2795184Sek110237 flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL]; 2805184Sek110237 2815184Sek110237 filebench_log(LOG_DEBUG_IMPL, "reading stats %s", name); 2825184Sek110237 2835184Sek110237 if (globalstats == NULL) 2845184Sek110237 globalstats = malloc(FLOW_TYPES * sizeof (flowstat_t)); 2855184Sek110237 2865184Sek110237 if (strcmp(name, "iocount") == 0) { 2876212Saw148015 fbint_t stat; 2886212Saw148015 2896212Saw148015 stat = iostat->fs_count + aiostat->fs_count; 2906212Saw148015 VAR_SET_INT(var, stat); 2916286Saw148015 filebench_log(LOG_DEBUG_IMPL, "reading stats %s = %llu", 2926286Saw148015 name, (u_longlong_t)stat); 2935184Sek110237 return (var); 2945184Sek110237 } 2955184Sek110237 2965184Sek110237 if (strcmp(name, "iorate") == 0) { 2976212Saw148015 fbint_t stat; 2986212Saw148015 2995184Sek110237 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 3006212Saw148015 stat = (iostat->fs_count + aiostat->fs_count) / 3015184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS); 3026212Saw148015 VAR_SET_INT(var, stat); 3035184Sek110237 return (var); 3045184Sek110237 } 3055184Sek110237 3065184Sek110237 3075184Sek110237 if (strcmp(name, "ioreadrate") == 0) { 3086212Saw148015 fbint_t stat; 3096212Saw148015 3105184Sek110237 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 3116212Saw148015 stat = (iostat->fs_rcount + aiostat->fs_rcount) / 3125184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS); 3136212Saw148015 VAR_SET_INT(var, stat); 3145184Sek110237 return (var); 3155184Sek110237 } 3165184Sek110237 3175184Sek110237 3185184Sek110237 if (strcmp(name, "iowriterate") == 0) { 3196212Saw148015 fbint_t stat; 3206212Saw148015 3215184Sek110237 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 3226212Saw148015 stat = (iostat->fs_wcount + aiostat->fs_wcount) / 3235184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS); 3246212Saw148015 VAR_SET_INT(var, stat); 3255184Sek110237 return (var); 3265184Sek110237 } 3275184Sek110237 3285184Sek110237 3295184Sek110237 if (strcmp(name, "iobandwidth") == 0) { 3306212Saw148015 fbint_t stat; 3316212Saw148015 3325184Sek110237 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 3336212Saw148015 stat = 3345184Sek110237 ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) / 3355184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS); 3366212Saw148015 VAR_SET_INT(var, stat); 3375184Sek110237 return (var); 3385184Sek110237 } 3395184Sek110237 3405184Sek110237 if (strcmp(name, "iolatency") == 0) { 3416212Saw148015 fbint_t stat; 3426212Saw148015 3436212Saw148015 stat = iostat->fs_count ? iostat->fs_mstate[FLOW_MSTATE_LAT] / 3445184Sek110237 (iostat->fs_count * 1000UL) : 0; 3456212Saw148015 VAR_SET_INT(var, stat); 3465184Sek110237 return (var); 3475184Sek110237 } 3485184Sek110237 3495184Sek110237 if (strcmp(name, "iocpu") == 0) { 3506212Saw148015 fbint_t stat; 3516212Saw148015 3526212Saw148015 stat = (iostat->fs_count + aiostat->fs_count) ? 3535184Sek110237 (iostat->fs_mstate[FLOW_MSTATE_CPU] + 3545184Sek110237 aiostat->fs_mstate[FLOW_MSTATE_CPU]) / ((iostat->fs_count + 3555184Sek110237 aiostat->fs_count) * 1000UL) : 0; 3566212Saw148015 VAR_SET_INT(var, stat); 3575184Sek110237 return (var); 3585184Sek110237 } 3595184Sek110237 3605184Sek110237 3615184Sek110237 if (strcmp(name, "oheadcpu") == 0) { 3626212Saw148015 fbint_t stat; 3636212Saw148015 3646212Saw148015 stat = (iostat->fs_count + aiostat->fs_count) ? 3655184Sek110237 io_stats_ohead() / ((iostat->fs_count + 3665184Sek110237 aiostat->fs_count) * 1000UL) : 0; 3676212Saw148015 VAR_SET_INT(var, stat); 3685184Sek110237 return (var); 3695184Sek110237 } 3705184Sek110237 3715184Sek110237 if (strcmp(name, "iowait") == 0) { 3726212Saw148015 fbint_t stat; 3736212Saw148015 3746212Saw148015 stat = iostat->fs_count ? 3755184Sek110237 iostat->fs_mstate[FLOW_MSTATE_WAIT] / 3765184Sek110237 (iostat->fs_count * 1000UL) : 0; 3776212Saw148015 VAR_SET_INT(var, stat); 3785184Sek110237 return (var); 3795184Sek110237 } 3805184Sek110237 3815184Sek110237 if (strcmp(name, "syscpu") == 0) { 3826212Saw148015 fbint_t stat; 3836212Saw148015 3845184Sek110237 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 3856212Saw148015 stat = glstat->fs_syscpu / 1000.0; 3866212Saw148015 VAR_SET_INT(var, stat); 3875184Sek110237 return (var); 3885184Sek110237 } 3895184Sek110237 3905184Sek110237 if (strcmp(name, "iocpusys") == 0) { 3916212Saw148015 fbint_t stat; 3926212Saw148015 3936212Saw148015 stat = (iostat->fs_count + aiostat->fs_count) ? 3945184Sek110237 iostat->fs_syscpu / ((iostat->fs_count + 3955184Sek110237 aiostat->fs_count) * 1000UL) : 0; 3965184Sek110237 3976212Saw148015 VAR_SET_INT(var, stat); 3985184Sek110237 return (var); 3995184Sek110237 } 4005184Sek110237 4015184Sek110237 filebench_log(LOG_DEBUG_IMPL, 4025184Sek110237 "error reading stats %s", name); 4035184Sek110237 4045184Sek110237 return (NULL); 4055184Sek110237 } 4065184Sek110237 4075184Sek110237 /* 4085184Sek110237 * Initializes the static variable "stats_cputime" with the 4095184Sek110237 * current cpu time, for use by kstats_read_cpu_relative. 4105184Sek110237 */ 4115184Sek110237 void 4125184Sek110237 stats_init(void) 4135184Sek110237 { 4145184Sek110237 #if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT) 4155184Sek110237 stats_cputime = kstats_read_cpu(); 4165184Sek110237 #else 4175184Sek110237 stats_cputime = 0; 4185184Sek110237 #endif /* HAVE_LIBKSTAT */ 4195184Sek110237 } 4205184Sek110237 4215184Sek110237 /* 4225184Sek110237 * Add a flowstat b to a, leave sum in a. 4235184Sek110237 */ 4245184Sek110237 static void 4255184Sek110237 stats_add(flowstat_t *a, flowstat_t *b) 4265184Sek110237 { 4275184Sek110237 int i; 4285184Sek110237 4295184Sek110237 a->fs_count += b->fs_count; 4305184Sek110237 a->fs_rcount += b->fs_rcount; 4315184Sek110237 a->fs_wcount += b->fs_wcount; 4325184Sek110237 a->fs_bytes += b->fs_bytes; 4335184Sek110237 a->fs_rbytes += b->fs_rbytes; 4345184Sek110237 a->fs_wbytes += b->fs_wbytes; 4355184Sek110237 4365184Sek110237 for (i = 0; i < FLOW_MSTATES; i++) 4375184Sek110237 a->fs_mstate[i] += b->fs_mstate[i]; 4385184Sek110237 } 4395184Sek110237 4405184Sek110237 /* 4415184Sek110237 * Takes a "snapshot" of the global statistics. Actually, it calculates 4425184Sek110237 * them from the local statistics maintained by each flowop. 4435184Sek110237 * First the routine pauses filebench, then rolls the statistics for 4445184Sek110237 * each flowop into its associated FLOW_MASTER flowop. 4455184Sek110237 * Next all the FLOW_MASTER flowops' statistics are written 4465184Sek110237 * to the log file followed by the global totals. Then filebench 4475184Sek110237 * operation is allowed to resume. 4485184Sek110237 */ 4495184Sek110237 void 4505184Sek110237 stats_snap(void) 4515184Sek110237 { 4525184Sek110237 flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 4535184Sek110237 flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 4545184Sek110237 flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL]; 4555184Sek110237 hrtime_t cputime; 4565184Sek110237 flowop_t *flowop; 4575184Sek110237 char *str; 4585184Sek110237 4595184Sek110237 if (globalstats == NULL) { 4605184Sek110237 filebench_log(LOG_ERROR, 4615184Sek110237 "'stats snap' called before 'stats clear'"); 4625184Sek110237 return; 4635184Sek110237 } 4645184Sek110237 4656084Saw148015 /* don't print out if run ended in error */ 4666391Saw148015 if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR) { 4676084Saw148015 filebench_log(LOG_ERROR, 4686084Saw148015 "NO VALID RESULTS! FileBench run terminated prematurely"); 4696084Saw148015 return; 4706084Saw148015 } 4716084Saw148015 4725184Sek110237 globalstats->fs_etime = gethrtime(); 4735184Sek110237 4745184Sek110237 filebench_log(LOG_DEBUG_SCRIPT, "Stats period = %ds", 4755184Sek110237 (globalstats->fs_etime - globalstats->fs_stime) / 1000000000); 4765184Sek110237 4775184Sek110237 /* Freeze statistics during update */ 4786391Saw148015 filebench_shm->shm_bequiet = 1; 4795184Sek110237 4806391Saw148015 flowop = filebench_shm->shm_flowoplist; 4815184Sek110237 while (flowop) { 4825184Sek110237 flowop_t *flowop_master; 4835184Sek110237 4846212Saw148015 if (flowop->fo_instance <= FLOW_DEFINITION) { 4855184Sek110237 flowop = flowop->fo_next; 4865184Sek110237 continue; 4875184Sek110237 } 4885184Sek110237 4896212Saw148015 flowop_master = flowop_find_one(flowop->fo_name, FLOW_MASTER); 4905184Sek110237 4915184Sek110237 /* Roll up per-flowop into global stats */ 4925184Sek110237 stats_add(&globalstats[flowop->fo_type], 4935184Sek110237 &flowop->fo_stats); 4945184Sek110237 stats_add(&globalstats[FLOW_TYPE_GLOBAL], 4955184Sek110237 &flowop->fo_stats); 4965184Sek110237 4975184Sek110237 if (flowop_master && IS_FLOW_ACTIVE(flowop)) { 4985184Sek110237 flowop_master->fo_stats.fs_active++; 4995184Sek110237 } 5005184Sek110237 5015184Sek110237 if (flowop_master) { 5025184Sek110237 /* Roll up per-flow stats into master */ 5035184Sek110237 flowop_master->fo_stats.fs_children++; 5045184Sek110237 stats_add(&flowop_master->fo_stats, &flowop->fo_stats); 5055184Sek110237 } else { 5065184Sek110237 filebench_log(LOG_DEBUG_NEVER, 5075184Sek110237 "flowop_stats could not find %s", 5085184Sek110237 flowop->fo_name); 5095184Sek110237 } 5105184Sek110237 5115184Sek110237 filebench_log(LOG_DEBUG_SCRIPT, 5125184Sek110237 "flowop %-20s-%4d - %5d ops, %5.1lf, ops/s %5.1lfmb/s " 5135184Sek110237 "%8.3fms/op", 5145184Sek110237 flowop->fo_name, 5155184Sek110237 flowop->fo_instance, 5165184Sek110237 flowop->fo_stats.fs_count, 5175184Sek110237 flowop->fo_stats.fs_count / 5185184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5195184Sek110237 (flowop->fo_stats.fs_bytes / (1024 * 1024)) / 5205184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5215184Sek110237 flowop->fo_stats.fs_count ? 5225184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] / 5235184Sek110237 (flowop->fo_stats.fs_count * 1000000.0) : 0); 5245184Sek110237 5255184Sek110237 flowop = flowop->fo_next; 5265184Sek110237 5275184Sek110237 } 5285184Sek110237 5295184Sek110237 #if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT) 5305184Sek110237 cputime = kstats_read_cpu_relative(); 5315184Sek110237 #endif /* HAVE_LIBKSTAT */ 5325184Sek110237 5335184Sek110237 filebench_log(LOG_DEBUG_IMPL, 5346286Saw148015 "cputime = %llu, ohead = %llu", 5356286Saw148015 (u_longlong_t)(cputime / 1000000000), 5366286Saw148015 (u_longlong_t)(io_stats_ohead() / 1000000000)); 5375184Sek110237 iostat->fs_syscpu = 5385184Sek110237 (cputime > io_stats_ohead()) ? 5395184Sek110237 (cputime - io_stats_ohead()) : 0; 5405184Sek110237 glstat->fs_syscpu = 5415184Sek110237 (cputime > gl_stats_ohead()) ? 5425184Sek110237 (cputime - gl_stats_ohead()) : 0; 5435184Sek110237 5445184Sek110237 5456391Saw148015 flowop = filebench_shm->shm_flowoplist; 5465184Sek110237 str = malloc(1048576); 5476613Sek110237 *str = '\0'; 5485184Sek110237 (void) strcpy(str, "Per-Operation Breakdown\n"); 5495184Sek110237 while (flowop) { 5505184Sek110237 char line[1024]; 5515184Sek110237 5525184Sek110237 if (flowop->fo_instance != FLOW_MASTER) { 5535184Sek110237 flowop = flowop->fo_next; 5545184Sek110237 continue; 5555184Sek110237 } 5565184Sek110237 5575184Sek110237 (void) snprintf(line, sizeof (line), "%-20s %8.0lfops/s " 5585184Sek110237 "%5.1lfmb/s %8.1fms/op %8.0fus/op-cpu\n", 5595184Sek110237 flowop->fo_name, 5605184Sek110237 flowop->fo_stats.fs_count / 5615184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5625184Sek110237 (flowop->fo_stats.fs_bytes / (1024 * 1024)) / 5635184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5645184Sek110237 flowop->fo_stats.fs_count ? 5655184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] / 5665184Sek110237 (flowop->fo_stats.fs_count * 1000000.0) : 0, 5675184Sek110237 flowop->fo_stats.fs_count ? 5685184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] / 5695184Sek110237 (flowop->fo_stats.fs_count * 1000.0) : 0); 5705184Sek110237 (void) strcat(str, line); 5715184Sek110237 5725184Sek110237 flowop = flowop->fo_next; 5735184Sek110237 } 5745184Sek110237 5755184Sek110237 filebench_log(LOG_INFO, "%s", str); 5765184Sek110237 free(str); 5775184Sek110237 5785184Sek110237 filebench_log(LOG_INFO, 5797736SAndrew.W.Wilson@sun.com "\nIO Summary: %5d ops, %5.1lf ops/s, (%0.0lf/%0.0lf r/w) " 5805184Sek110237 "%5.1lfmb/s, %6.0fus cpu/op, %5.1fms latency", 5815184Sek110237 iostat->fs_count + aiostat->fs_count, 5825184Sek110237 (iostat->fs_count + aiostat->fs_count) / 5835184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5845184Sek110237 (iostat->fs_rcount + aiostat->fs_rcount) / 5855184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5865184Sek110237 (iostat->fs_wcount + aiostat->fs_wcount) / 5875184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5885184Sek110237 ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) / 5895184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 5905184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + 5915184Sek110237 aiostat->fs_rcount + aiostat->fs_wcount) ? 5925184Sek110237 (iostat->fs_syscpu / 1000.0) / 5935184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + 5945184Sek110237 aiostat->fs_rcount + aiostat->fs_wcount) : 0, 5955184Sek110237 (iostat->fs_rcount + iostat->fs_wcount) ? 5965184Sek110237 iostat->fs_mstate[FLOW_MSTATE_LAT] / 5975184Sek110237 ((iostat->fs_rcount + iostat->fs_wcount) * 1000000.0) : 0); 5985184Sek110237 5995184Sek110237 6006391Saw148015 filebench_shm->shm_bequiet = 0; 6015184Sek110237 } 6025184Sek110237 6035184Sek110237 /* 6045184Sek110237 * Dumps the per-operation statistics and global statistics to the dump file. 6055184Sek110237 */ 6065184Sek110237 void 6075184Sek110237 stats_dump(char *filename) 6085184Sek110237 { 6095184Sek110237 flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 6105184Sek110237 flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 6115184Sek110237 flowop_t *flowop; 6125184Sek110237 6136084Saw148015 /* don't dump stats if run ended in error */ 6146391Saw148015 if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR) 6156084Saw148015 return; 6166084Saw148015 6176391Saw148015 (void) strcpy(filebench_shm->shm_dump_filename, filename); 6185184Sek110237 6195184Sek110237 filebench_log(LOG_INFO, "in statsdump %s", filename); 6205184Sek110237 6216391Saw148015 if (filebench_shm->shm_dump_fd > 0) { 6226391Saw148015 (void) close(filebench_shm->shm_dump_fd); 6236391Saw148015 filebench_shm->shm_dump_fd = -1; 6245184Sek110237 } 6255184Sek110237 6265184Sek110237 filebench_log(LOG_DUMP, "Flowop totals:"); 6275184Sek110237 6286391Saw148015 flowop = filebench_shm->shm_flowoplist; 6295184Sek110237 while (flowop) { 6305184Sek110237 6315184Sek110237 if (flowop->fo_instance != FLOW_MASTER) { 6325184Sek110237 flowop = flowop->fo_next; 6335184Sek110237 continue; 6345184Sek110237 } 6355184Sek110237 6365184Sek110237 filebench_log(LOG_DUMP, 6375184Sek110237 "%-20s %8.0lfops/s %5.1lfmb/s " 6385184Sek110237 "%8.1fms/op %8.0fus/op-cpu", 6395184Sek110237 flowop->fo_name, 6405184Sek110237 flowop->fo_stats.fs_count / 6415184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6425184Sek110237 (flowop->fo_stats.fs_bytes / (1024 * 1024)) / 6435184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6445184Sek110237 flowop->fo_stats.fs_count ? 6455184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] / 6465184Sek110237 (flowop->fo_stats.fs_count * 1000000.0) : 0, 6475184Sek110237 flowop->fo_stats.fs_count ? 6485184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] / 6495184Sek110237 (flowop->fo_stats.fs_count * 1000.0) : 0); 6505184Sek110237 6515184Sek110237 flowop = flowop->fo_next; 6525184Sek110237 } 6535184Sek110237 6545184Sek110237 filebench_log(LOG_DUMP, ""); 6555184Sek110237 filebench_log(LOG_DUMP, 6565184Sek110237 "IO Summary: %8d ops %8.1lf ops/s, %8.0lf/%0.0lf r/w" 6575184Sek110237 "%8.1lfmb/s, %8.0fuscpu/op", 6585184Sek110237 6595184Sek110237 iostat->fs_count + aiostat->fs_count, 6605184Sek110237 (iostat->fs_count + aiostat->fs_count) / 6615184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6625184Sek110237 6635184Sek110237 (iostat->fs_rcount + aiostat->fs_rcount) / 6645184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6655184Sek110237 6665184Sek110237 (iostat->fs_wcount + aiostat->fs_wcount) / 6675184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6685184Sek110237 6695184Sek110237 ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) / 6705184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 6715184Sek110237 6725184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + 6735184Sek110237 aiostat->fs_rcount + aiostat->fs_wcount) ? 6745184Sek110237 (iostat->fs_syscpu / 1000.0) / 6755184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + 6765184Sek110237 aiostat->fs_rcount + aiostat->fs_wcount) : 0); 6775184Sek110237 } 6785184Sek110237 6795184Sek110237 /* 6805184Sek110237 * Same as stats_dump, but in xml format. 6815184Sek110237 */ 6825184Sek110237 void 6835184Sek110237 stats_xmldump(char *filename) 6845184Sek110237 { 6855184Sek110237 flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 6865184Sek110237 flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 6875184Sek110237 flowop_t *flowop; 6885184Sek110237 6896084Saw148015 /* don't dump stats if run ended in error */ 6906391Saw148015 if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR) 6916084Saw148015 return; 6926084Saw148015 6936391Saw148015 (void) strcpy(filebench_shm->shm_dump_filename, filename); 6945184Sek110237 6956391Saw148015 if (filebench_shm->shm_dump_fd > 0) { 6966391Saw148015 (void) close(filebench_shm->shm_dump_fd); 6976391Saw148015 filebench_shm->shm_dump_fd = -1; 6985184Sek110237 } 6995184Sek110237 7005184Sek110237 filebench_log(LOG_DUMP, "<stat_doc name=\"Filebench Workload\">"); 7015184Sek110237 filebench_log(LOG_DUMP, "<stat_group name=\"Flowop totals\">"); 7025184Sek110237 filebench_log(LOG_DUMP, "<cell_list>"); 7035184Sek110237 7046391Saw148015 flowop = filebench_shm->shm_flowoplist; 7055184Sek110237 while (flowop) { 7065184Sek110237 if (flowop->fo_instance != FLOW_MASTER) { 7075184Sek110237 flowop = flowop->fo_next; 7085184Sek110237 continue; 7095184Sek110237 } 7105184Sek110237 7115184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>", 7125184Sek110237 flowop->fo_stats.fs_count / 7135184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7145184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>", 7155184Sek110237 (flowop->fo_stats.fs_bytes / (1024 * 1024)) / 7165184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7175184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>", 7185184Sek110237 flowop->fo_stats.fs_count ? 7195184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] / 7205184Sek110237 (flowop->fo_stats.fs_count * 1000000.0) : 0); 7215184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>", 7225184Sek110237 flowop->fo_stats.fs_count ? 7235184Sek110237 flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] / 7245184Sek110237 (flowop->fo_stats.fs_count * 1000.0) : 0); 7255184Sek110237 7265184Sek110237 flowop = flowop->fo_next; 7275184Sek110237 } 7285184Sek110237 filebench_log(LOG_DUMP, "</cell_list>"); 7295184Sek110237 7305184Sek110237 filebench_log(LOG_DUMP, "<dim_list>"); 7315184Sek110237 filebench_log(LOG_DUMP, "<dim>"); 7325184Sek110237 filebench_log(LOG_DUMP, "<dimval>Operations/sec</dimval>"); 7335184Sek110237 filebench_log(LOG_DUMP, "<dimval>MB/sec</dimval>"); 7345184Sek110237 filebench_log(LOG_DUMP, "<dimval>Latency (ms per operation)</dimval>"); 7355184Sek110237 filebench_log(LOG_DUMP, "<dimval>CPU (us per operation)</dimval>"); 7365184Sek110237 filebench_log(LOG_DUMP, "</dim>"); 7375184Sek110237 7385184Sek110237 filebench_log(LOG_DUMP, "<dim>"); 7396391Saw148015 flowop = filebench_shm->shm_flowoplist; 7405184Sek110237 while (flowop) { 7415184Sek110237 if (flowop->fo_instance != FLOW_MASTER) { 7425184Sek110237 flowop = flowop->fo_next; 7435184Sek110237 continue; 7445184Sek110237 } 7455184Sek110237 filebench_log(LOG_DUMP, "<dimval>%s</dimval>", flowop->fo_name); 7465184Sek110237 flowop = flowop->fo_next; 7475184Sek110237 } 7485184Sek110237 filebench_log(LOG_DUMP, "</dim>"); 7495184Sek110237 filebench_log(LOG_DUMP, "</dim_list>"); 7505184Sek110237 filebench_log(LOG_DUMP, "</stat_group>"); 7515184Sek110237 7525184Sek110237 filebench_log(LOG_DUMP, "<stat_group name=\"IO Summary\">"); 7535184Sek110237 filebench_log(LOG_DUMP, "<cell_list>"); 7545184Sek110237 filebench_log(LOG_DUMP, "<cell>%0d</cell>", 7555184Sek110237 iostat->fs_count + aiostat->fs_count); 7565184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>", 7575184Sek110237 (iostat->fs_count + aiostat->fs_count) / 7585184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7595184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>", 7605184Sek110237 (iostat->fs_rcount + aiostat->fs_rcount) / 7615184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7625184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>", 7635184Sek110237 (iostat->fs_wcount + aiostat->fs_wcount) / 7645184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7655184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>", 7665184Sek110237 ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) / 7675184Sek110237 ((globalstats->fs_etime - globalstats->fs_stime) / FSECS)); 7685184Sek110237 filebench_log(LOG_DUMP, "<cell>%0.0f</cell>", 7695184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + aiostat->fs_rcount + 7705184Sek110237 aiostat->fs_wcount) ? (iostat->fs_syscpu / 1000.0) / 7715184Sek110237 (iostat->fs_rcount + iostat->fs_wcount + aiostat->fs_rcount + 7725184Sek110237 aiostat->fs_wcount) : 0); 7735184Sek110237 filebench_log(LOG_DUMP, "</cell_list>"); 7745184Sek110237 7755184Sek110237 filebench_log(LOG_DUMP, "<dim_list>"); 7765184Sek110237 filebench_log(LOG_DUMP, "<dim>"); 7775184Sek110237 filebench_log(LOG_DUMP, "<dimval>Operations</dimval>"); 7785184Sek110237 filebench_log(LOG_DUMP, "<dimval>Operations/sec</dimval>"); 7795184Sek110237 filebench_log(LOG_DUMP, "<dimval>Reads</dimval>"); 7805184Sek110237 filebench_log(LOG_DUMP, "<dimval>Writes</dimval>"); 7815184Sek110237 filebench_log(LOG_DUMP, "<dimval>MB/sec</dimval>"); 7825184Sek110237 filebench_log(LOG_DUMP, "<dimval>CPU (us per operation)</dimval>"); 7835184Sek110237 filebench_log(LOG_DUMP, "</dim>"); 7845184Sek110237 7855184Sek110237 filebench_log(LOG_DUMP, "<dim>"); 7865184Sek110237 filebench_log(LOG_DUMP, "<dimval>IO Summary</dimval>"); 7875184Sek110237 filebench_log(LOG_DUMP, "</dim>"); 7885184Sek110237 filebench_log(LOG_DUMP, "</dim_list>"); 7895184Sek110237 filebench_log(LOG_DUMP, "</stat_group>"); 7905184Sek110237 filebench_log(LOG_DUMP, "</stat_doc>"); 7915184Sek110237 } 7925184Sek110237 7935184Sek110237 /* 7947736SAndrew.W.Wilson@sun.com * same as stats_dump, but in computer friendly format 7957736SAndrew.W.Wilson@sun.com */ 7967736SAndrew.W.Wilson@sun.com void 7977736SAndrew.W.Wilson@sun.com stats_multidump(char *filename) 7987736SAndrew.W.Wilson@sun.com { 7997736SAndrew.W.Wilson@sun.com flowstat_t *iostat = &globalstats[FLOW_TYPE_IO]; 8007736SAndrew.W.Wilson@sun.com flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; 8017736SAndrew.W.Wilson@sun.com flowop_t *flowop; 8027736SAndrew.W.Wilson@sun.com 8037736SAndrew.W.Wilson@sun.com /* don't dump stats if run ended in error */ 8047736SAndrew.W.Wilson@sun.com if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR) 8057736SAndrew.W.Wilson@sun.com return; 8067736SAndrew.W.Wilson@sun.com 8077736SAndrew.W.Wilson@sun.com (void) strcpy(filebench_shm->shm_dump_filename, filename); 8087736SAndrew.W.Wilson@sun.com 8097736SAndrew.W.Wilson@sun.com filebench_log(LOG_INFO, "in statsmultidump %s", filename); 8107736SAndrew.W.Wilson@sun.com 8117736SAndrew.W.Wilson@sun.com if (filebench_shm->shm_dump_fd > 0) { 8127736SAndrew.W.Wilson@sun.com (void) close(filebench_shm->shm_dump_fd); 8137736SAndrew.W.Wilson@sun.com filebench_shm->shm_dump_fd = -1; 8147736SAndrew.W.Wilson@sun.com } 8157736SAndrew.W.Wilson@sun.com 8167736SAndrew.W.Wilson@sun.com filebench_log(LOG_DUMP, "Flowop totals:"); 8177736SAndrew.W.Wilson@sun.com 8187736SAndrew.W.Wilson@sun.com flowop = filebench_shm->shm_flowoplist; 8197736SAndrew.W.Wilson@sun.com while (flowop) { 8207736SAndrew.W.Wilson@sun.com 8217736SAndrew.W.Wilson@sun.com if (flowop->fo_instance != FLOW_MASTER) { 8227736SAndrew.W.Wilson@sun.com flowop = flowop->fo_next; 8237736SAndrew.W.Wilson@sun.com continue; 8247736SAndrew.W.Wilson@sun.com } 8257736SAndrew.W.Wilson@sun.com 8267736SAndrew.W.Wilson@sun.com filebench_log(LOG_DUMP, 8277736SAndrew.W.Wilson@sun.com "%s\t%1.0lf\t%1.1lf\t%1.1f\t%1.0f", 8287736SAndrew.W.Wilson@sun.com flowop->fo_name, 8297736SAndrew.W.Wilson@sun.com flowop->fo_stats.fs_count / 8307736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8317736SAndrew.W.Wilson@sun.com (flowop->fo_stats.fs_bytes / (1024 * 1024)) / 8327736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8337736SAndrew.W.Wilson@sun.com flowop->fo_stats.fs_count ? 8347736SAndrew.W.Wilson@sun.com flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] / 8357736SAndrew.W.Wilson@sun.com (flowop->fo_stats.fs_count * 1000000.0) : 0, 8367736SAndrew.W.Wilson@sun.com flowop->fo_stats.fs_count ? 8377736SAndrew.W.Wilson@sun.com flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] / 8387736SAndrew.W.Wilson@sun.com (flowop->fo_stats.fs_count * 1000.0) : 0); 8397736SAndrew.W.Wilson@sun.com 8407736SAndrew.W.Wilson@sun.com flowop = flowop->fo_next; 8417736SAndrew.W.Wilson@sun.com } 8427736SAndrew.W.Wilson@sun.com 8437736SAndrew.W.Wilson@sun.com filebench_log(LOG_DUMP, ""); 8447736SAndrew.W.Wilson@sun.com filebench_log(LOG_DUMP, 8457736SAndrew.W.Wilson@sun.com "IO Summary:\n%d\t%1.1lf\t%1.0lf\t%1.0lf\t%1.1lf\t%1.0f\t%1.1f\n", 8467736SAndrew.W.Wilson@sun.com 8477736SAndrew.W.Wilson@sun.com iostat->fs_count + aiostat->fs_count, 8487736SAndrew.W.Wilson@sun.com 8497736SAndrew.W.Wilson@sun.com (iostat->fs_count + aiostat->fs_count) / 8507736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8517736SAndrew.W.Wilson@sun.com 8527736SAndrew.W.Wilson@sun.com (iostat->fs_rcount + aiostat->fs_rcount) / 8537736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8547736SAndrew.W.Wilson@sun.com 8557736SAndrew.W.Wilson@sun.com (iostat->fs_wcount + aiostat->fs_wcount) / 8567736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8577736SAndrew.W.Wilson@sun.com 8587736SAndrew.W.Wilson@sun.com ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) / 8597736SAndrew.W.Wilson@sun.com ((globalstats->fs_etime - globalstats->fs_stime) / FSECS), 8607736SAndrew.W.Wilson@sun.com 8617736SAndrew.W.Wilson@sun.com (iostat->fs_rcount + iostat->fs_wcount + 8627736SAndrew.W.Wilson@sun.com aiostat->fs_rcount + aiostat->fs_wcount) ? 8637736SAndrew.W.Wilson@sun.com (iostat->fs_syscpu / 1000.0) / 8647736SAndrew.W.Wilson@sun.com (iostat->fs_rcount + iostat->fs_wcount + 8657736SAndrew.W.Wilson@sun.com aiostat->fs_rcount + aiostat->fs_wcount) : 0, 8667736SAndrew.W.Wilson@sun.com 8677736SAndrew.W.Wilson@sun.com (iostat->fs_rcount + iostat->fs_wcount) ? 8687736SAndrew.W.Wilson@sun.com iostat->fs_mstate[FLOW_MSTATE_LAT] / 8697736SAndrew.W.Wilson@sun.com ((iostat->fs_rcount + iostat->fs_wcount) * 1000000.0) : 0); 8707736SAndrew.W.Wilson@sun.com } 8717736SAndrew.W.Wilson@sun.com 8727736SAndrew.W.Wilson@sun.com /* 8735184Sek110237 * Clears all the statistics variables (fo_stats) for every defined flowop. 8745184Sek110237 * It also creates a global flowstat table if one doesn't already exist and 8755184Sek110237 * clears it. 8765184Sek110237 */ 8775184Sek110237 void 8785184Sek110237 stats_clear(void) 8795184Sek110237 { 8805184Sek110237 flowop_t *flowop; 8815184Sek110237 8825184Sek110237 #ifdef HAVE_LIBKSTAT 8835184Sek110237 stats_cputime = kstats_read_cpu(); 8845184Sek110237 #else 8855184Sek110237 stats_cputime = 0; 8865184Sek110237 #endif /* HAVE_LIBKSTAT */ 8875184Sek110237 8885184Sek110237 if (globalstats == NULL) 8895184Sek110237 globalstats = malloc(FLOW_TYPES * sizeof (flowstat_t)); 8905184Sek110237 8915184Sek110237 (void) memset(globalstats, 0, FLOW_TYPES * sizeof (flowstat_t)); 8925184Sek110237 8936391Saw148015 flowop = filebench_shm->shm_flowoplist; 8945184Sek110237 8955184Sek110237 while (flowop) { 8965184Sek110237 filebench_log(LOG_DEBUG_IMPL, "Clearing stats for %s-%d", 8975184Sek110237 flowop->fo_name, 8985184Sek110237 flowop->fo_instance); 8995184Sek110237 (void) memset(&flowop->fo_stats, 0, sizeof (flowstat_t)); 9005184Sek110237 flowop = flowop->fo_next; 9015184Sek110237 } 9025184Sek110237 9035184Sek110237 (void) memset(globalstats, 0, sizeof (flowstat_t)); 9045184Sek110237 globalstats->fs_stime = gethrtime(); 9055184Sek110237 } 906