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