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