127aa4769SMichael Reifenberger /*- 227aa4769SMichael Reifenberger * Copyright (c) 2014 327aa4769SMichael Reifenberger * The Regents of the University of California. All rights reserved. 427aa4769SMichael Reifenberger * 527aa4769SMichael Reifenberger * Redistribution and use in source and binary forms, with or without 627aa4769SMichael Reifenberger * modification, are permitted provided that the following conditions 727aa4769SMichael Reifenberger * are met: 827aa4769SMichael Reifenberger * 1. Redistributions of source code must retain the above copyright 927aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer. 1027aa4769SMichael Reifenberger * 2. Redistributions in binary form must reproduce the above copyright 1127aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer in the 1227aa4769SMichael Reifenberger * documentation and/or other materials provided with the distribution. 13fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 1427aa4769SMichael Reifenberger * may be used to endorse or promote products derived from this software 1527aa4769SMichael Reifenberger * without specific prior written permission. 1627aa4769SMichael Reifenberger * 1727aa4769SMichael Reifenberger * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1827aa4769SMichael Reifenberger * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1927aa4769SMichael Reifenberger * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2027aa4769SMichael Reifenberger * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2127aa4769SMichael Reifenberger * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2227aa4769SMichael Reifenberger * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2327aa4769SMichael Reifenberger * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2427aa4769SMichael Reifenberger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2527aa4769SMichael Reifenberger * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2627aa4769SMichael Reifenberger * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2727aa4769SMichael Reifenberger * SUCH DAMAGE. 2827aa4769SMichael Reifenberger */ 2927aa4769SMichael Reifenberger 3027aa4769SMichael Reifenberger #include <sys/cdefs.h> 3127aa4769SMichael Reifenberger __FBSDID("$FreeBSD$"); 3227aa4769SMichael Reifenberger 3327aa4769SMichael Reifenberger #include <sys/types.h> 3427aa4769SMichael Reifenberger #include <sys/sysctl.h> 3527aa4769SMichael Reifenberger 36*970bdbf5SMichael Tuexen #include <inttypes.h> 3727aa4769SMichael Reifenberger #include <string.h> 3827aa4769SMichael Reifenberger 3927aa4769SMichael Reifenberger #include "systat.h" 4027aa4769SMichael Reifenberger #include "extern.h" 4127aa4769SMichael Reifenberger 4227aa4769SMichael Reifenberger struct zfield{ 4327aa4769SMichael Reifenberger uint64_t arcstats; 4427aa4769SMichael Reifenberger uint64_t arcstats_demand_data; 4527aa4769SMichael Reifenberger uint64_t arcstats_demand_metadata; 4627aa4769SMichael Reifenberger uint64_t arcstats_prefetch_data; 4727aa4769SMichael Reifenberger uint64_t arcstats_prefetch_metadata; 4827aa4769SMichael Reifenberger uint64_t zfetchstats; 4927aa4769SMichael Reifenberger uint64_t arcstats_l2; 5027aa4769SMichael Reifenberger uint64_t vdev_cache_stats; 5127aa4769SMichael Reifenberger }; 5227aa4769SMichael Reifenberger 5327aa4769SMichael Reifenberger static struct zarcstats { 5427aa4769SMichael Reifenberger struct zfield hits; 5527aa4769SMichael Reifenberger struct zfield misses; 5627aa4769SMichael Reifenberger } curstat, initstat, oldstat; 5727aa4769SMichael Reifenberger 5827aa4769SMichael Reifenberger static void 5927aa4769SMichael Reifenberger getinfo(struct zarcstats *ls); 6027aa4769SMichael Reifenberger 6127aa4769SMichael Reifenberger WINDOW * 6227aa4769SMichael Reifenberger openzarc(void) 6327aa4769SMichael Reifenberger { 6427aa4769SMichael Reifenberger return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 6527aa4769SMichael Reifenberger } 6627aa4769SMichael Reifenberger 6727aa4769SMichael Reifenberger void 6827aa4769SMichael Reifenberger closezarc(WINDOW *w) 6927aa4769SMichael Reifenberger { 7027aa4769SMichael Reifenberger if (w == NULL) 7127aa4769SMichael Reifenberger return; 7227aa4769SMichael Reifenberger wclear(w); 7327aa4769SMichael Reifenberger wrefresh(w); 7427aa4769SMichael Reifenberger delwin(w); 7527aa4769SMichael Reifenberger } 7627aa4769SMichael Reifenberger 7727aa4769SMichael Reifenberger void 7827aa4769SMichael Reifenberger labelzarc(void) 7927aa4769SMichael Reifenberger { 8027aa4769SMichael Reifenberger wmove(wnd, 0, 0); wclrtoeol(wnd); 8127aa4769SMichael Reifenberger mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s", 8227aa4769SMichael Reifenberger "rate", "hits", "misses", "total hits", "total misses"); 8327aa4769SMichael Reifenberger #define L(row, str) mvwprintw(wnd, row, 5, str); \ 8427aa4769SMichael Reifenberger mvwprintw(wnd, row, 31, ":"); \ 8527aa4769SMichael Reifenberger mvwprintw(wnd, row, 31+4, "%%") 8627aa4769SMichael Reifenberger L(1, "arcstats"); 8727aa4769SMichael Reifenberger L(2, "arcstats.demand_data"); 8827aa4769SMichael Reifenberger L(3, "arcstats.demand_metadata"); 8927aa4769SMichael Reifenberger L(4, "arcstats.prefetch_data"); 9027aa4769SMichael Reifenberger L(5, "arcstats.prefetch_metadata"); 9127aa4769SMichael Reifenberger L(6, "zfetchstats"); 9227aa4769SMichael Reifenberger L(7, "arcstats.l2"); 9327aa4769SMichael Reifenberger L(8, "vdev_cache_stats"); 9427aa4769SMichael Reifenberger #undef L 9527aa4769SMichael Reifenberger } 9627aa4769SMichael Reifenberger 9727aa4769SMichael Reifenberger static int calc(uint64_t hits, uint64_t misses) 9827aa4769SMichael Reifenberger { 9927aa4769SMichael Reifenberger if( hits ) 10027aa4769SMichael Reifenberger return 100 * hits / ( hits + misses ); 10127aa4769SMichael Reifenberger else 10227aa4769SMichael Reifenberger return 0; 10327aa4769SMichael Reifenberger } 10427aa4769SMichael Reifenberger 10527aa4769SMichael Reifenberger static void 10627aa4769SMichael Reifenberger domode(struct zarcstats *delta, struct zarcstats *rate) 10727aa4769SMichael Reifenberger { 10827aa4769SMichael Reifenberger #define DO(stat) \ 10927aa4769SMichael Reifenberger delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \ 11027aa4769SMichael Reifenberger delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \ 11127aa4769SMichael Reifenberger rate->hits.stat = calc(delta->hits.stat, delta->misses.stat) 11227aa4769SMichael Reifenberger DO(arcstats); 11327aa4769SMichael Reifenberger DO(arcstats_demand_data); 11427aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 11527aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 11627aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 11727aa4769SMichael Reifenberger DO(zfetchstats); 11827aa4769SMichael Reifenberger DO(arcstats_l2); 11927aa4769SMichael Reifenberger DO(vdev_cache_stats); 12027aa4769SMichael Reifenberger DO(arcstats); 12127aa4769SMichael Reifenberger DO(arcstats_demand_data); 12227aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 12327aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 12427aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 12527aa4769SMichael Reifenberger DO(zfetchstats); 12627aa4769SMichael Reifenberger DO(arcstats_l2); 12727aa4769SMichael Reifenberger DO(vdev_cache_stats); 12827aa4769SMichael Reifenberger #undef DO 12927aa4769SMichael Reifenberger } 13027aa4769SMichael Reifenberger 13127aa4769SMichael Reifenberger void 13227aa4769SMichael Reifenberger showzarc(void) 13327aa4769SMichael Reifenberger { 13427aa4769SMichael Reifenberger struct zarcstats delta, rate; 13527aa4769SMichael Reifenberger 13627aa4769SMichael Reifenberger memset(&delta, 0, sizeof delta); 13727aa4769SMichael Reifenberger memset(&rate, 0, sizeof rate); 13827aa4769SMichael Reifenberger 13927aa4769SMichael Reifenberger domode(&delta, &rate); 14027aa4769SMichael Reifenberger 14127aa4769SMichael Reifenberger #define DO(stat, row, col, fmt) \ 14227aa4769SMichael Reifenberger mvwprintw(wnd, row, col, fmt, stat) 143*970bdbf5SMichael Tuexen #define R(row, stat) DO(rate.hits.stat, row, 31+1, "%3"PRIu64) 144*970bdbf5SMichael Tuexen #define H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7"PRIu64); \ 145*970bdbf5SMichael Tuexen DO(curstat.hits.stat, row, 31+1+5+8+8, "%12"PRIu64) 146*970bdbf5SMichael Tuexen #define M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7"PRIu64); \ 147*970bdbf5SMichael Tuexen DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12"PRIu64) 14827aa4769SMichael Reifenberger #define E(row, stat) R(row, stat); H(row, stat); M(row, stat); 14927aa4769SMichael Reifenberger E(1, arcstats); 15027aa4769SMichael Reifenberger E(2, arcstats_demand_data); 15127aa4769SMichael Reifenberger E(3, arcstats_demand_metadata); 15227aa4769SMichael Reifenberger E(4, arcstats_prefetch_data); 15327aa4769SMichael Reifenberger E(5, arcstats_prefetch_metadata); 15427aa4769SMichael Reifenberger E(6, zfetchstats); 15527aa4769SMichael Reifenberger E(7, arcstats_l2); 15627aa4769SMichael Reifenberger E(8, vdev_cache_stats); 15727aa4769SMichael Reifenberger #undef DO 15827aa4769SMichael Reifenberger #undef E 15927aa4769SMichael Reifenberger #undef M 16027aa4769SMichael Reifenberger #undef H 16127aa4769SMichael Reifenberger #undef R 16227aa4769SMichael Reifenberger } 16327aa4769SMichael Reifenberger 16427aa4769SMichael Reifenberger int 16527aa4769SMichael Reifenberger initzarc(void) 16627aa4769SMichael Reifenberger { 16727aa4769SMichael Reifenberger getinfo(&initstat); 16827aa4769SMichael Reifenberger curstat = oldstat = initstat; 16927aa4769SMichael Reifenberger return 1; 17027aa4769SMichael Reifenberger } 17127aa4769SMichael Reifenberger 17227aa4769SMichael Reifenberger void 17327aa4769SMichael Reifenberger resetzarc(void) 17427aa4769SMichael Reifenberger { 17527aa4769SMichael Reifenberger initzarc(); 17627aa4769SMichael Reifenberger } 17727aa4769SMichael Reifenberger 17827aa4769SMichael Reifenberger static void 17927aa4769SMichael Reifenberger getinfo(struct zarcstats *ls) 18027aa4769SMichael Reifenberger { 18127aa4769SMichael Reifenberger size_t size = sizeof( ls->hits.arcstats ); 18227aa4769SMichael Reifenberger if ( sysctlbyname("kstat.zfs.misc.arcstats.hits", 18327aa4769SMichael Reifenberger &ls->hits.arcstats, &size, NULL, 0 ) != 0 ) 18427aa4769SMichael Reifenberger return; 18527aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.misses", 18627aa4769SMichael Reifenberger ls->misses.arcstats); 18727aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits", 18827aa4769SMichael Reifenberger ls->hits.arcstats_demand_data); 18927aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses", 19027aa4769SMichael Reifenberger ls->misses.arcstats_demand_data); 19127aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits", 19227aa4769SMichael Reifenberger ls->hits.arcstats_demand_metadata); 19327aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses", 19427aa4769SMichael Reifenberger ls->misses.arcstats_demand_metadata); 19527aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits", 19627aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_data); 19727aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses", 19827aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_data); 19927aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits", 20027aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_metadata); 20127aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses", 20227aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_metadata); 20327aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.hits", 20427aa4769SMichael Reifenberger ls->hits.zfetchstats); 20527aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.misses", 20627aa4769SMichael Reifenberger ls->misses.zfetchstats); 20727aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits", 20827aa4769SMichael Reifenberger ls->hits.arcstats_l2); 20927aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses", 21027aa4769SMichael Reifenberger ls->misses.arcstats_l2); 21127aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits", 21227aa4769SMichael Reifenberger ls->hits.vdev_cache_stats); 21327aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses", 21427aa4769SMichael Reifenberger ls->misses.vdev_cache_stats); 21527aa4769SMichael Reifenberger } 21627aa4769SMichael Reifenberger 21727aa4769SMichael Reifenberger void 21827aa4769SMichael Reifenberger fetchzarc(void) 21927aa4769SMichael Reifenberger { 22027aa4769SMichael Reifenberger oldstat = curstat; 22127aa4769SMichael Reifenberger getinfo(&curstat); 22227aa4769SMichael Reifenberger } 223