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