127aa4769SMichael Reifenberger /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 39e16b953SKirk McKusick * 44bde6353SMichael Reifenberger * Copyright (c) 2014 - 2017, 2019 Yoshihiro Ota 527aa4769SMichael Reifenberger * 627aa4769SMichael Reifenberger * Redistribution and use in source and binary forms, with or without 727aa4769SMichael Reifenberger * modification, are permitted provided that the following conditions 827aa4769SMichael Reifenberger * are met: 927aa4769SMichael Reifenberger * 1. Redistributions of source code must retain the above copyright 1027aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer. 1127aa4769SMichael Reifenberger * 2. Redistributions in binary form must reproduce the above copyright 1227aa4769SMichael Reifenberger * notice, this list of conditions and the following disclaimer in the 1327aa4769SMichael Reifenberger * documentation and/or other materials provided with the distribution. 1427aa4769SMichael Reifenberger * 159e16b953SKirk McKusick * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1627aa4769SMichael Reifenberger * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1727aa4769SMichael Reifenberger * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 189e16b953SKirk McKusick * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1927aa4769SMichael Reifenberger * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2027aa4769SMichael Reifenberger * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2127aa4769SMichael Reifenberger * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2227aa4769SMichael Reifenberger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2327aa4769SMichael Reifenberger * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2427aa4769SMichael Reifenberger * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2527aa4769SMichael Reifenberger * SUCH DAMAGE. 2627aa4769SMichael Reifenberger */ 2727aa4769SMichael Reifenberger 2827aa4769SMichael Reifenberger #include <sys/cdefs.h> 2927aa4769SMichael Reifenberger __FBSDID("$FreeBSD$"); 3027aa4769SMichael Reifenberger 3127aa4769SMichael Reifenberger #include <sys/types.h> 3227aa4769SMichael Reifenberger #include <sys/sysctl.h> 3327aa4769SMichael Reifenberger 34970bdbf5SMichael Tuexen #include <inttypes.h> 3527aa4769SMichael Reifenberger #include <string.h> 3645518845SMichael Reifenberger #include <err.h> 374bde6353SMichael Reifenberger #include <libutil.h> 3827aa4769SMichael Reifenberger 3927aa4769SMichael Reifenberger #include "systat.h" 4027aa4769SMichael Reifenberger #include "extern.h" 4145518845SMichael Reifenberger #include "devs.h" 4227aa4769SMichael Reifenberger 4327aa4769SMichael Reifenberger struct zfield { 4427aa4769SMichael Reifenberger uint64_t arcstats; 4527aa4769SMichael Reifenberger uint64_t arcstats_demand_data; 4627aa4769SMichael Reifenberger uint64_t arcstats_demand_metadata; 4727aa4769SMichael Reifenberger uint64_t arcstats_prefetch_data; 4827aa4769SMichael Reifenberger uint64_t arcstats_prefetch_metadata; 4927aa4769SMichael Reifenberger uint64_t zfetchstats; 5027aa4769SMichael Reifenberger uint64_t arcstats_l2; 5127aa4769SMichael Reifenberger uint64_t vdev_cache_stats; 5227aa4769SMichael Reifenberger }; 5327aa4769SMichael Reifenberger 5427aa4769SMichael Reifenberger static struct zarcstats { 5527aa4769SMichael Reifenberger struct zfield hits; 5627aa4769SMichael Reifenberger struct zfield misses; 5727aa4769SMichael Reifenberger } curstat, initstat, oldstat; 5827aa4769SMichael Reifenberger 594bde6353SMichael Reifenberger struct zarcrates { 604bde6353SMichael Reifenberger struct zfield current; 614bde6353SMichael Reifenberger struct zfield total; 624bde6353SMichael Reifenberger }; 634bde6353SMichael Reifenberger 6427aa4769SMichael Reifenberger static void 6527aa4769SMichael Reifenberger getinfo(struct zarcstats *ls); 6627aa4769SMichael Reifenberger 6727aa4769SMichael Reifenberger WINDOW * 6827aa4769SMichael Reifenberger openzarc(void) 6927aa4769SMichael Reifenberger { 704bde6353SMichael Reifenberger 7127aa4769SMichael Reifenberger return (subwin(stdscr, LINES - 3 - 1, 0, MAINWIN_ROW, 0)); 7227aa4769SMichael Reifenberger } 7327aa4769SMichael Reifenberger 7427aa4769SMichael Reifenberger void 7527aa4769SMichael Reifenberger closezarc(WINDOW *w) 7627aa4769SMichael Reifenberger { 774bde6353SMichael Reifenberger 7827aa4769SMichael Reifenberger if (w == NULL) 7927aa4769SMichael Reifenberger return; 8027aa4769SMichael Reifenberger wclear(w); 8127aa4769SMichael Reifenberger wrefresh(w); 8227aa4769SMichael Reifenberger delwin(w); 8327aa4769SMichael Reifenberger } 8427aa4769SMichael Reifenberger 8527aa4769SMichael Reifenberger void 8627aa4769SMichael Reifenberger labelzarc(void) 8727aa4769SMichael Reifenberger { 8845518845SMichael Reifenberger int row = 1; 894bde6353SMichael Reifenberger 9027aa4769SMichael Reifenberger wmove(wnd, 0, 0); wclrtoeol(wnd); 914bde6353SMichael Reifenberger mvwprintw(wnd, 0, 31+1, "%4.4s %6.6s %6.6s | Total %4.4s %6.6s %6.6s", 924bde6353SMichael Reifenberger "Rate", "Hits", "Misses", "Rate", "Hits", "Misses"); 934bde6353SMichael Reifenberger #define L(str) mvwprintw(wnd, row++, 5, \ 944bde6353SMichael Reifenberger "%-26.26s: %% | %%", #str) 9545518845SMichael Reifenberger L(arcstats); 9645518845SMichael Reifenberger L(arcstats.demand_data); 9745518845SMichael Reifenberger L(arcstats.demand_metadata); 9845518845SMichael Reifenberger L(arcstats.prefetch_data); 9945518845SMichael Reifenberger L(arcstats.prefetch_metadata); 10045518845SMichael Reifenberger L(zfetchstats); 10145518845SMichael Reifenberger L(arcstats.l2); 10245518845SMichael Reifenberger L(vdev_cache_stats); 10327aa4769SMichael Reifenberger #undef L 10445518845SMichael Reifenberger dslabel(12, 0, 18); 10527aa4769SMichael Reifenberger } 10627aa4769SMichael Reifenberger 1074bde6353SMichael Reifenberger static int 1084bde6353SMichael Reifenberger calc_rate(uint64_t hits, uint64_t misses) 10927aa4769SMichael Reifenberger { 11027aa4769SMichael Reifenberger if(hits) 11127aa4769SMichael Reifenberger return 100 * hits / (hits + misses); 11227aa4769SMichael Reifenberger else 11327aa4769SMichael Reifenberger return 0; 11427aa4769SMichael Reifenberger } 11527aa4769SMichael Reifenberger 11627aa4769SMichael Reifenberger static void 1174bde6353SMichael Reifenberger domode(struct zarcstats *delta, struct zarcrates *rate) 11827aa4769SMichael Reifenberger { 11927aa4769SMichael Reifenberger #define DO(stat) \ 12027aa4769SMichael Reifenberger delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \ 12127aa4769SMichael Reifenberger delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \ 1224bde6353SMichael Reifenberger rate->current.stat = calc_rate(delta->hits.stat, delta->misses.stat); \ 1234bde6353SMichael Reifenberger rate->total.stat = calc_rate(curstat.hits.stat, curstat.misses.stat) 12427aa4769SMichael Reifenberger DO(arcstats); 12527aa4769SMichael Reifenberger DO(arcstats_demand_data); 12627aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 12727aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 12827aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 12927aa4769SMichael Reifenberger DO(zfetchstats); 13027aa4769SMichael Reifenberger DO(arcstats_l2); 13127aa4769SMichael Reifenberger DO(vdev_cache_stats); 13227aa4769SMichael Reifenberger DO(arcstats); 13327aa4769SMichael Reifenberger DO(arcstats_demand_data); 13427aa4769SMichael Reifenberger DO(arcstats_demand_metadata); 13527aa4769SMichael Reifenberger DO(arcstats_prefetch_data); 13627aa4769SMichael Reifenberger DO(arcstats_prefetch_metadata); 13727aa4769SMichael Reifenberger DO(zfetchstats); 13827aa4769SMichael Reifenberger DO(arcstats_l2); 13927aa4769SMichael Reifenberger DO(vdev_cache_stats); 14027aa4769SMichael Reifenberger #undef DO 14127aa4769SMichael Reifenberger } 14227aa4769SMichael Reifenberger 14327aa4769SMichael Reifenberger void 14427aa4769SMichael Reifenberger showzarc(void) 14527aa4769SMichael Reifenberger { 14645518845SMichael Reifenberger int row = 1; 1474bde6353SMichael Reifenberger struct zarcstats delta = {}; 1484bde6353SMichael Reifenberger struct zarcrates rate = {}; 14927aa4769SMichael Reifenberger 15027aa4769SMichael Reifenberger domode(&delta, &rate); 15127aa4769SMichael Reifenberger 1524bde6353SMichael Reifenberger #define DO(stat, col, width) \ 1534bde6353SMichael Reifenberger sysputuint64(wnd, row, col, width, stat, HN_DIVISOR_1000) 1544bde6353SMichael Reifenberger #define RATES(stat) mvwprintw(wnd, row, 31+1, "%3"PRIu64, rate.current.stat);\ 1554bde6353SMichael Reifenberger mvwprintw(wnd, row, 31+1+5+7+7+8, "%3"PRIu64, rate.total.stat) 1564bde6353SMichael Reifenberger #define HITS(stat) DO(delta.hits.stat, 31+1+5, 6); \ 1574bde6353SMichael Reifenberger DO(curstat.hits.stat, 31+1+5+7+7+8+5, 6) 1584bde6353SMichael Reifenberger #define MISSES(stat) DO(delta.misses.stat, 31+1+5+7, 6); \ 1594bde6353SMichael Reifenberger DO(curstat.misses.stat, 31+1+5+7+7+8+5+7, 6) 1604bde6353SMichael Reifenberger #define E(stat) RATES(stat); HITS(stat); MISSES(stat); ++row 16145518845SMichael Reifenberger E(arcstats); 16245518845SMichael Reifenberger E(arcstats_demand_data); 16345518845SMichael Reifenberger E(arcstats_demand_metadata); 16445518845SMichael Reifenberger E(arcstats_prefetch_data); 16545518845SMichael Reifenberger E(arcstats_prefetch_metadata); 16645518845SMichael Reifenberger E(zfetchstats); 16745518845SMichael Reifenberger E(arcstats_l2); 16845518845SMichael Reifenberger E(vdev_cache_stats); 16927aa4769SMichael Reifenberger #undef DO 17027aa4769SMichael Reifenberger #undef E 1714bde6353SMichael Reifenberger #undef MISSES 1724bde6353SMichael Reifenberger #undef HITS 1734bde6353SMichael Reifenberger #undef RATES 17445518845SMichael Reifenberger dsshow(12, 0, 18, &cur_dev, &last_dev); 17527aa4769SMichael Reifenberger } 17627aa4769SMichael Reifenberger 17727aa4769SMichael Reifenberger int 17827aa4769SMichael Reifenberger initzarc(void) 17927aa4769SMichael Reifenberger { 18045518845SMichael Reifenberger dsinit(12); 18127aa4769SMichael Reifenberger getinfo(&initstat); 18227aa4769SMichael Reifenberger curstat = oldstat = initstat; 18345518845SMichael Reifenberger 18427aa4769SMichael Reifenberger return 1; 18527aa4769SMichael Reifenberger } 18627aa4769SMichael Reifenberger 18727aa4769SMichael Reifenberger void 18827aa4769SMichael Reifenberger resetzarc(void) 18927aa4769SMichael Reifenberger { 1904bde6353SMichael Reifenberger 19127aa4769SMichael Reifenberger initzarc(); 19227aa4769SMichael Reifenberger } 19327aa4769SMichael Reifenberger 19427aa4769SMichael Reifenberger static void 19527aa4769SMichael Reifenberger getinfo(struct zarcstats *ls) 19627aa4769SMichael Reifenberger { 19745518845SMichael Reifenberger struct devinfo *tmp_dinfo; 19845518845SMichael Reifenberger 19945518845SMichael Reifenberger tmp_dinfo = last_dev.dinfo; 20045518845SMichael Reifenberger last_dev.dinfo = cur_dev.dinfo; 20145518845SMichael Reifenberger cur_dev.dinfo = tmp_dinfo; 20245518845SMichael Reifenberger 20345518845SMichael Reifenberger last_dev.snap_time = cur_dev.snap_time; 20445518845SMichael Reifenberger dsgetinfo(&cur_dev); 20545518845SMichael Reifenberger 20627aa4769SMichael Reifenberger size_t size = sizeof(ls->hits.arcstats); 20727aa4769SMichael Reifenberger if (sysctlbyname("kstat.zfs.misc.arcstats.hits", 20827aa4769SMichael Reifenberger &ls->hits.arcstats, &size, NULL, 0) != 0) 20927aa4769SMichael Reifenberger return; 21027aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.misses", 21127aa4769SMichael Reifenberger ls->misses.arcstats); 21227aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits", 21327aa4769SMichael Reifenberger ls->hits.arcstats_demand_data); 21427aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses", 21527aa4769SMichael Reifenberger ls->misses.arcstats_demand_data); 21627aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits", 21727aa4769SMichael Reifenberger ls->hits.arcstats_demand_metadata); 21827aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses", 21927aa4769SMichael Reifenberger ls->misses.arcstats_demand_metadata); 22027aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits", 22127aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_data); 22227aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses", 22327aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_data); 22427aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits", 22527aa4769SMichael Reifenberger ls->hits.arcstats_prefetch_metadata); 22627aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses", 22727aa4769SMichael Reifenberger ls->misses.arcstats_prefetch_metadata); 22827aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.hits", 22927aa4769SMichael Reifenberger ls->hits.zfetchstats); 23027aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.zfetchstats.misses", 23127aa4769SMichael Reifenberger ls->misses.zfetchstats); 23227aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits", 23327aa4769SMichael Reifenberger ls->hits.arcstats_l2); 23427aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses", 23527aa4769SMichael Reifenberger ls->misses.arcstats_l2); 23627aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits", 23727aa4769SMichael Reifenberger ls->hits.vdev_cache_stats); 23827aa4769SMichael Reifenberger GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses", 23927aa4769SMichael Reifenberger ls->misses.vdev_cache_stats); 24027aa4769SMichael Reifenberger } 24127aa4769SMichael Reifenberger 24227aa4769SMichael Reifenberger void 24327aa4769SMichael Reifenberger fetchzarc(void) 24427aa4769SMichael Reifenberger { 2454bde6353SMichael Reifenberger 24627aa4769SMichael Reifenberger oldstat = curstat; 24727aa4769SMichael Reifenberger getinfo(&curstat); 24827aa4769SMichael Reifenberger } 249