1*27aa4769SMichael Reifenberger /*- 2*27aa4769SMichael Reifenberger * Copyright (c) 2014 3*27aa4769SMichael Reifenberger * The Regents of the University of California. All rights reserved. 4*27aa4769SMichael Reifenberger * 5*27aa4769SMichael Reifenberger * Redistribution and use in source and binary forms, with or without 6*27aa4769SMichael Reifenberger * modification, are permitted provided that the following conditions 7*27aa4769SMichael Reifenberger * are met: 8*27aa4769SMichael Reifenberger * 1. Redistributions of source code must retain the above copyright 9*27aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer. 10*27aa4769SMichael Reifenberger * 2. Redistributions in binary form must reproduce the above copyright 11*27aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer in the 12*27aa4769SMichael Reifenberger * documentation and/or other materials provided with the distribution. 13*27aa4769SMichael Reifenberger * 4. Neither the name of the University nor the names of its contributors 14*27aa4769SMichael Reifenberger * may be used to endorse or promote products derived from this software 15*27aa4769SMichael Reifenberger * without specific prior written permission. 16*27aa4769SMichael Reifenberger * 17*27aa4769SMichael Reifenberger * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*27aa4769SMichael Reifenberger * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*27aa4769SMichael Reifenberger * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*27aa4769SMichael Reifenberger * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*27aa4769SMichael Reifenberger * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*27aa4769SMichael Reifenberger * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*27aa4769SMichael Reifenberger * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*27aa4769SMichael Reifenberger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*27aa4769SMichael Reifenberger * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*27aa4769SMichael Reifenberger * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*27aa4769SMichael Reifenberger * SUCH DAMAGE. 28*27aa4769SMichael Reifenberger */ 29*27aa4769SMichael Reifenberger 30*27aa4769SMichael Reifenberger #include <sys/cdefs.h> 31*27aa4769SMichael Reifenberger __FBSDID("$FreeBSD$"); 32*27aa4769SMichael Reifenberger 33*27aa4769SMichael Reifenberger #include <sys/types.h> 34*27aa4769SMichael Reifenberger #include <sys/sysctl.h> 35*27aa4769SMichael Reifenberger 36*27aa4769SMichael Reifenberger #include <string.h> 37*27aa4769SMichael Reifenberger 38*27aa4769SMichael Reifenberger #include "systat.h" 39*27aa4769SMichael Reifenberger #include "extern.h" 40*27aa4769SMichael Reifenberger 41*27aa4769SMichael Reifenberger struct zfield{ 42*27aa4769SMichael Reifenberger uint64_t arcstats; 43*27aa4769SMichael Reifenberger uint64_t arcstats_demand_data; 44*27aa4769SMichael Reifenberger uint64_t arcstats_demand_metadata; 45*27aa4769SMichael Reifenberger uint64_t arcstats_prefetch_data; 46*27aa4769SMichael Reifenberger uint64_t arcstats_prefetch_metadata; 47*27aa4769SMichael Reifenberger uint64_t zfetchstats; 48*27aa4769SMichael Reifenberger uint64_t arcstats_l2; 49*27aa4769SMichael Reifenberger uint64_t vdev_cache_stats; 50*27aa4769SMichael Reifenberger }; 51*27aa4769SMichael Reifenberger 52*27aa4769SMichael Reifenberger static struct zarcstats { 53*27aa4769SMichael Reifenberger struct zfield hits; 54*27aa4769SMichael Reifenberger struct zfield misses; 55*27aa4769SMichael Reifenberger } curstat, initstat, oldstat; 56*27aa4769SMichael Reifenberger 57*27aa4769SMichael Reifenberger static void 58*27aa4769SMichael Reifenberger getinfo(struct zarcstats *ls); 59*27aa4769SMichael Reifenberger 60*27aa4769SMichael Reifenberger WINDOW * 61*27aa4769SMichael Reifenberger openzarc(void) 62*27aa4769SMichael Reifenberger { 63*27aa4769SMichael Reifenberger return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 64*27aa4769SMichael Reifenberger } 65*27aa4769SMichael Reifenberger 66*27aa4769SMichael Reifenberger void 67*27aa4769SMichael Reifenberger closezarc(WINDOW *w) 68*27aa4769SMichael Reifenberger { 69*27aa4769SMichael Reifenberger if (w == NULL) 70*27aa4769SMichael Reifenberger return; 71*27aa4769SMichael Reifenberger wclear(w); 72*27aa4769SMichael Reifenberger wrefresh(w); 73*27aa4769SMichael Reifenberger delwin(w); 74*27aa4769SMichael Reifenberger } 75*27aa4769SMichael Reifenberger 76*27aa4769SMichael Reifenberger void 77*27aa4769SMichael Reifenberger labelzarc(void) 78*27aa4769SMichael Reifenberger { 79*27aa4769SMichael Reifenberger wmove(wnd, 0, 0); wclrtoeol(wnd); 80*27aa4769SMichael Reifenberger mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s", 81*27aa4769SMichael Reifenberger "rate", "hits", "misses", "total hits", "total misses"); 82*27aa4769SMichael Reifenberger #define L(row, str) mvwprintw(wnd, row, 5, str); \ 83*27aa4769SMichael Reifenberger mvwprintw(wnd, row, 31, ":"); \ 84*27aa4769SMichael Reifenberger mvwprintw(wnd, row, 31+4, "%%") 85*27aa4769SMichael Reifenberger L(1, "arcstats"); 86*27aa4769SMichael Reifenberger L(2, "arcstats.demand_data"); 87*27aa4769SMichael Reifenberger L(3, "arcstats.demand_metadata"); 88*27aa4769SMichael Reifenberger L(4, "arcstats.prefetch_data"); 89*27aa4769SMichael Reifenberger L(5, "arcstats.prefetch_metadata"); 90*27aa4769SMichael Reifenberger L(6, "zfetchstats"); 91*27aa4769SMichael Reifenberger L(7, "arcstats.l2"); 92*27aa4769SMichael Reifenberger L(8, "vdev_cache_stats"); 93*27aa4769SMichael Reifenberger #undef L 94*27aa4769SMichael Reifenberger } 95*27aa4769SMichael Reifenberger 96*27aa4769SMichael Reifenberger static int calc(uint64_t hits, uint64_t misses) 97*27aa4769SMichael Reifenberger { 98*27aa4769SMichael Reifenberger if( hits ) 99*27aa4769SMichael Reifenberger return 100 * hits / ( hits + misses ); 100*27aa4769SMichael Reifenberger else 101*27aa4769SMichael Reifenberger return 0; 102*27aa4769SMichael Reifenberger } 103*27aa4769SMichael Reifenberger 104*27aa4769SMichael Reifenberger static void 105*27aa4769SMichael Reifenberger domode(struct zarcstats *delta, struct zarcstats *rate) 106*27aa4769SMichael Reifenberger { 107*27aa4769SMichael Reifenberger #define DO(stat) \ 108*27aa4769SMichael Reifenberger delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \ 109*27aa4769SMichael Reifenberger delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \ 110*27aa4769SMichael Reifenberger rate->hits.stat = calc(delta->hits.stat, delta->misses.stat) 111*27aa4769SMichael Reifenberger DO(arcstats); 112*27aa4769SMichael Reifenberger DO(arcstats_demand_data); 113*27aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 114*27aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 115*27aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 116*27aa4769SMichael Reifenberger DO(zfetchstats); 117*27aa4769SMichael Reifenberger DO(arcstats_l2); 118*27aa4769SMichael Reifenberger DO(vdev_cache_stats); 119*27aa4769SMichael Reifenberger DO(arcstats); 120*27aa4769SMichael Reifenberger DO(arcstats_demand_data); 121*27aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 122*27aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 123*27aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 124*27aa4769SMichael Reifenberger DO(zfetchstats); 125*27aa4769SMichael Reifenberger DO(arcstats_l2); 126*27aa4769SMichael Reifenberger DO(vdev_cache_stats); 127*27aa4769SMichael Reifenberger #undef DO 128*27aa4769SMichael Reifenberger } 129*27aa4769SMichael Reifenberger 130*27aa4769SMichael Reifenberger void 131*27aa4769SMichael Reifenberger showzarc(void) 132*27aa4769SMichael Reifenberger { 133*27aa4769SMichael Reifenberger struct zarcstats delta, rate; 134*27aa4769SMichael Reifenberger 135*27aa4769SMichael Reifenberger memset(&delta, 0, sizeof delta); 136*27aa4769SMichael Reifenberger memset(&rate, 0, sizeof rate); 137*27aa4769SMichael Reifenberger 138*27aa4769SMichael Reifenberger domode(&delta, &rate); 139*27aa4769SMichael Reifenberger 140*27aa4769SMichael Reifenberger #define DO(stat, row, col, fmt) \ 141*27aa4769SMichael Reifenberger mvwprintw(wnd, row, col, fmt, stat) 142*27aa4769SMichael Reifenberger #define R(row, stat) DO(rate.hits.stat, row, 31+1, "%3lu") 143*27aa4769SMichael Reifenberger #define H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7lu"); \ 144*27aa4769SMichael Reifenberger DO(curstat.hits.stat, row, 31+1+5+8+8, "%12lu") 145*27aa4769SMichael Reifenberger #define M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7lu"); \ 146*27aa4769SMichael Reifenberger DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12lu") 147*27aa4769SMichael Reifenberger #define E(row, stat) R(row, stat); H(row, stat); M(row, stat); 148*27aa4769SMichael Reifenberger E(1, arcstats); 149*27aa4769SMichael Reifenberger E(2, arcstats_demand_data); 150*27aa4769SMichael Reifenberger E(3, arcstats_demand_metadata); 151*27aa4769SMichael Reifenberger E(4, arcstats_prefetch_data); 152*27aa4769SMichael Reifenberger E(5, arcstats_prefetch_metadata); 153*27aa4769SMichael Reifenberger E(6, zfetchstats); 154*27aa4769SMichael Reifenberger E(7, arcstats_l2); 155*27aa4769SMichael Reifenberger E(8, vdev_cache_stats); 156*27aa4769SMichael Reifenberger #undef DO 157*27aa4769SMichael Reifenberger #undef E 158*27aa4769SMichael Reifenberger #undef M 159*27aa4769SMichael Reifenberger #undef H 160*27aa4769SMichael Reifenberger #undef R 161*27aa4769SMichael Reifenberger } 162*27aa4769SMichael Reifenberger 163*27aa4769SMichael Reifenberger int 164*27aa4769SMichael Reifenberger initzarc(void) 165*27aa4769SMichael Reifenberger { 166*27aa4769SMichael Reifenberger getinfo(&initstat); 167*27aa4769SMichael Reifenberger curstat = oldstat = initstat; 168*27aa4769SMichael Reifenberger return 1; 169*27aa4769SMichael Reifenberger } 170*27aa4769SMichael Reifenberger 171*27aa4769SMichael Reifenberger void 172*27aa4769SMichael Reifenberger resetzarc(void) 173*27aa4769SMichael Reifenberger { 174*27aa4769SMichael Reifenberger initzarc(); 175*27aa4769SMichael Reifenberger } 176*27aa4769SMichael Reifenberger 177*27aa4769SMichael Reifenberger static void 178*27aa4769SMichael Reifenberger getinfo(struct zarcstats *ls) 179*27aa4769SMichael Reifenberger { 180*27aa4769SMichael Reifenberger size_t size = sizeof( ls->hits.arcstats ); 181*27aa4769SMichael Reifenberger if ( sysctlbyname("kstat.zfs.misc.arcstats.hits", 182*27aa4769SMichael Reifenberger &ls->hits.arcstats, &size, NULL, 0 ) != 0 ) 183*27aa4769SMichael Reifenberger return; 184*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.misses", 185*27aa4769SMichael Reifenberger ls->misses.arcstats); 186*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits", 187*27aa4769SMichael Reifenberger ls->hits.arcstats_demand_data); 188*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses", 189*27aa4769SMichael Reifenberger ls->misses.arcstats_demand_data); 190*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits", 191*27aa4769SMichael Reifenberger ls->hits.arcstats_demand_metadata); 192*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses", 193*27aa4769SMichael Reifenberger ls->misses.arcstats_demand_metadata); 194*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits", 195*27aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_data); 196*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses", 197*27aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_data); 198*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits", 199*27aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_metadata); 200*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses", 201*27aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_metadata); 202*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.hits", 203*27aa4769SMichael Reifenberger ls->hits.zfetchstats); 204*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.misses", 205*27aa4769SMichael Reifenberger ls->misses.zfetchstats); 206*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits", 207*27aa4769SMichael Reifenberger ls->hits.arcstats_l2); 208*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses", 209*27aa4769SMichael Reifenberger ls->misses.arcstats_l2); 210*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits", 211*27aa4769SMichael Reifenberger ls->hits.vdev_cache_stats); 212*27aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses", 213*27aa4769SMichael Reifenberger ls->misses.vdev_cache_stats); 214*27aa4769SMichael Reifenberger } 215*27aa4769SMichael Reifenberger 216*27aa4769SMichael Reifenberger void 217*27aa4769SMichael Reifenberger fetchzarc(void) 218*27aa4769SMichael Reifenberger { 219*27aa4769SMichael Reifenberger oldstat = curstat; 220*27aa4769SMichael Reifenberger getinfo(&curstat); 221*27aa4769SMichael Reifenberger } 222