1288306Smr/*- 2368931Smr * Copyright (c) 2014 - 2017, 2019 Yoshihiro Ota 3288306Smr * 4288306Smr * Redistribution and use in source and binary forms, with or without 5288306Smr * modification, are permitted provided that the following conditions 6288306Smr * are met: 7288306Smr * 1. Redistributions of source code must retain the above copyright 8288306Smr * notice, this list of conditions and the following disclaimer. 9288306Smr * 2. Redistributions in binary form must reproduce the above copyright 10288306Smr * notice, this list of conditions and the following disclaimer in the 11288306Smr * documentation and/or other materials provided with the distribution. 12288306Smr * 4. Neither the name of the University nor the names of its contributors 13288306Smr * may be used to endorse or promote products derived from this software 14288306Smr * without specific prior written permission. 15288306Smr * 16288306Smr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17288306Smr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18288306Smr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19288306Smr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20288306Smr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21288306Smr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22288306Smr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23288306Smr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24288306Smr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25288306Smr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26288306Smr * SUCH DAMAGE. 27288306Smr */ 28288306Smr 29288306Smr#include <sys/cdefs.h> 30288306Smr__FBSDID("$FreeBSD: stable/11/usr.bin/systat/zarc.c 368931 2021-01-05 20:02:55Z mr $"); 31288306Smr 32288306Smr#include <sys/types.h> 33288306Smr#include <sys/sysctl.h> 34288306Smr 35368931Smr#include <inttypes.h> 36288306Smr#include <string.h> 37368931Smr#include <err.h> 38368931Smr#include <libutil.h> 39288306Smr 40288306Smr#include "systat.h" 41288306Smr#include "extern.h" 42368931Smr#include "devs.h" 43288306Smr 44368931Smrstruct zfield { 45288306Smr uint64_t arcstats; 46288306Smr uint64_t arcstats_demand_data; 47288306Smr uint64_t arcstats_demand_metadata; 48288306Smr uint64_t arcstats_prefetch_data; 49288306Smr uint64_t arcstats_prefetch_metadata; 50288306Smr uint64_t zfetchstats; 51288306Smr uint64_t arcstats_l2; 52288306Smr uint64_t vdev_cache_stats; 53288306Smr}; 54288306Smr 55288306Smrstatic struct zarcstats { 56288306Smr struct zfield hits; 57288306Smr struct zfield misses; 58288306Smr} curstat, initstat, oldstat; 59288306Smr 60368931Smrstruct zarcrates { 61368931Smr struct zfield current; 62368931Smr struct zfield total; 63368931Smr}; 64368931Smr 65288306Smrstatic void 66288306Smrgetinfo(struct zarcstats *ls); 67288306Smr 68288306SmrWINDOW * 69288306Smropenzarc(void) 70288306Smr{ 71368931Smr 72368931Smr return (subwin(stdscr, LINES - 3 - 1, 0, MAINWIN_ROW, 0)); 73288306Smr} 74288306Smr 75288306Smrvoid 76288306Smrclosezarc(WINDOW *w) 77288306Smr{ 78368931Smr 79288306Smr if (w == NULL) 80288306Smr return; 81288306Smr wclear(w); 82288306Smr wrefresh(w); 83288306Smr delwin(w); 84288306Smr} 85288306Smr 86288306Smrvoid 87288306Smrlabelzarc(void) 88288306Smr{ 89368931Smr int row = 1; 90368931Smr 91288306Smr wmove(wnd, 0, 0); wclrtoeol(wnd); 92368931Smr mvwprintw(wnd, 0, 31+1, "%4.4s %6.6s %6.6s | Total %4.4s %6.6s %6.6s", 93368931Smr "Rate", "Hits", "Misses", "Rate", "Hits", "Misses"); 94368931Smr#define L(str) mvwprintw(wnd, row++, 5, \ 95368931Smr "%-26.26s: %% | %%", #str) 96368931Smr L(arcstats); 97368931Smr L(arcstats.demand_data); 98368931Smr L(arcstats.demand_metadata); 99368931Smr L(arcstats.prefetch_data); 100368931Smr L(arcstats.prefetch_metadata); 101368931Smr L(zfetchstats); 102368931Smr L(arcstats.l2); 103368931Smr L(vdev_cache_stats); 104288306Smr#undef L 105368931Smr dslabel(12, 0, 18); 106288306Smr} 107288306Smr 108368931Smrstatic int 109368931Smrcalc_rate(uint64_t hits, uint64_t misses) 110288306Smr{ 111368931Smr if(hits) 112368931Smr return 100 * hits / (hits + misses); 113288306Smr else 114288306Smr return 0; 115288306Smr} 116288306Smr 117288306Smrstatic void 118368931Smrdomode(struct zarcstats *delta, struct zarcrates *rate) 119288306Smr{ 120288306Smr#define DO(stat) \ 121288306Smr delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \ 122288306Smr delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \ 123368931Smr rate->current.stat = calc_rate(delta->hits.stat, delta->misses.stat); \ 124368931Smr rate->total.stat = calc_rate(curstat.hits.stat, curstat.misses.stat) 125288306Smr DO(arcstats); 126288306Smr DO(arcstats_demand_data); 127288306Smr DO(arcstats_demand_metadata); 128288306Smr DO(arcstats_prefetch_data); 129288306Smr DO(arcstats_prefetch_metadata); 130288306Smr DO(zfetchstats); 131288306Smr DO(arcstats_l2); 132288306Smr DO(vdev_cache_stats); 133288306Smr DO(arcstats); 134288306Smr DO(arcstats_demand_data); 135288306Smr DO(arcstats_demand_metadata); 136288306Smr DO(arcstats_prefetch_data); 137288306Smr DO(arcstats_prefetch_metadata); 138288306Smr DO(zfetchstats); 139288306Smr DO(arcstats_l2); 140288306Smr DO(vdev_cache_stats); 141288306Smr#undef DO 142288306Smr} 143288306Smr 144288306Smrvoid 145288306Smrshowzarc(void) 146288306Smr{ 147368931Smr int row = 1; 148368931Smr struct zarcstats delta = {}; 149368931Smr struct zarcrates rate = {}; 150288306Smr 151288306Smr domode(&delta, &rate); 152288306Smr 153368931Smr#define DO(stat, col, width) \ 154368931Smr sysputuint64(wnd, row, col, width, stat, HN_DIVISOR_1000) 155368931Smr#define RATES(stat) mvwprintw(wnd, row, 31+1, "%3"PRIu64, rate.current.stat);\ 156368931Smr mvwprintw(wnd, row, 31+1+5+7+7+8, "%3"PRIu64, rate.total.stat) 157368931Smr#define HITS(stat) DO(delta.hits.stat, 31+1+5, 6); \ 158368931Smr DO(curstat.hits.stat, 31+1+5+7+7+8+5, 6) 159368931Smr#define MISSES(stat) DO(delta.misses.stat, 31+1+5+7, 6); \ 160368931Smr DO(curstat.misses.stat, 31+1+5+7+7+8+5+7, 6) 161368931Smr#define E(stat) RATES(stat); HITS(stat); MISSES(stat); ++row 162368931Smr E(arcstats); 163368931Smr E(arcstats_demand_data); 164368931Smr E(arcstats_demand_metadata); 165368931Smr E(arcstats_prefetch_data); 166368931Smr E(arcstats_prefetch_metadata); 167368931Smr E(zfetchstats); 168368931Smr E(arcstats_l2); 169368931Smr E(vdev_cache_stats); 170288306Smr#undef DO 171288306Smr#undef E 172368931Smr#undef MISSES 173368931Smr#undef HITS 174368931Smr#undef RATES 175368931Smr dsshow(12, 0, 18, &cur_dev, &last_dev); 176288306Smr} 177288306Smr 178288306Smrint 179288306Smrinitzarc(void) 180288306Smr{ 181368931Smr dsinit(12); 182288306Smr getinfo(&initstat); 183288306Smr curstat = oldstat = initstat; 184368931Smr 185288306Smr return 1; 186288306Smr} 187288306Smr 188288306Smrvoid 189288306Smrresetzarc(void) 190288306Smr{ 191368931Smr 192288306Smr initzarc(); 193288306Smr} 194288306Smr 195288306Smrstatic void 196288306Smrgetinfo(struct zarcstats *ls) 197288306Smr{ 198368931Smr struct devinfo *tmp_dinfo; 199368931Smr 200368931Smr tmp_dinfo = last_dev.dinfo; 201368931Smr last_dev.dinfo = cur_dev.dinfo; 202368931Smr cur_dev.dinfo = tmp_dinfo; 203368931Smr 204368931Smr last_dev.snap_time = cur_dev.snap_time; 205368931Smr dsgetinfo(&cur_dev); 206368931Smr 207368931Smr size_t size = sizeof(ls->hits.arcstats); 208368931Smr if (sysctlbyname("kstat.zfs.misc.arcstats.hits", 209368931Smr &ls->hits.arcstats, &size, NULL, 0) != 0) 210288306Smr return; 211288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.misses", 212288306Smr ls->misses.arcstats); 213288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits", 214288306Smr ls->hits.arcstats_demand_data); 215288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses", 216288306Smr ls->misses.arcstats_demand_data); 217288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits", 218288306Smr ls->hits.arcstats_demand_metadata); 219288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses", 220288306Smr ls->misses.arcstats_demand_metadata); 221288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits", 222288306Smr ls->hits.arcstats_prefetch_data); 223288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses", 224288306Smr ls->misses.arcstats_prefetch_data); 225288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits", 226288306Smr ls->hits.arcstats_prefetch_metadata); 227288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses", 228288306Smr ls->misses.arcstats_prefetch_metadata); 229288306Smr GETSYSCTL("kstat.zfs.misc.zfetchstats.hits", 230288306Smr ls->hits.zfetchstats); 231288306Smr GETSYSCTL("kstat.zfs.misc.zfetchstats.misses", 232288306Smr ls->misses.zfetchstats); 233288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits", 234288306Smr ls->hits.arcstats_l2); 235288306Smr GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses", 236288306Smr ls->misses.arcstats_l2); 237288306Smr GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits", 238288306Smr ls->hits.vdev_cache_stats); 239288306Smr GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses", 240288306Smr ls->misses.vdev_cache_stats); 241288306Smr} 242288306Smr 243288306Smrvoid 244288306Smrfetchzarc(void) 245288306Smr{ 246368931Smr 247288306Smr oldstat = curstat; 248288306Smr getinfo(&curstat); 249288306Smr} 250