xref: /freebsd/usr.bin/systat/zarc.c (revision 970bdbf5d75f082b69c41aa9372ed1a0eddd3419)
127aa4769SMichael Reifenberger /*-
227aa4769SMichael Reifenberger  * Copyright (c) 2014
327aa4769SMichael Reifenberger  *	The Regents of the University of California.  All rights reserved.
427aa4769SMichael Reifenberger  *
527aa4769SMichael Reifenberger  * Redistribution and use in source and binary forms, with or without
627aa4769SMichael Reifenberger  * modification, are permitted provided that the following conditions
727aa4769SMichael Reifenberger  * are met:
827aa4769SMichael Reifenberger  * 1. Redistributions of source code must retain the above copyright
927aa4769SMichael Reifenberger  *    notice, this list of conditions and the following disclaimer.
1027aa4769SMichael Reifenberger  * 2. Redistributions in binary form must reproduce the above copyright
1127aa4769SMichael Reifenberger  *    notice, this list of conditions and the following disclaimer in the
1227aa4769SMichael Reifenberger  *    documentation and/or other materials provided with the distribution.
13fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
1427aa4769SMichael Reifenberger  *    may be used to endorse or promote products derived from this software
1527aa4769SMichael Reifenberger  *    without specific prior written permission.
1627aa4769SMichael Reifenberger  *
1727aa4769SMichael Reifenberger  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1827aa4769SMichael Reifenberger  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1927aa4769SMichael Reifenberger  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2027aa4769SMichael Reifenberger  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2127aa4769SMichael Reifenberger  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2227aa4769SMichael Reifenberger  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2327aa4769SMichael Reifenberger  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2427aa4769SMichael Reifenberger  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2527aa4769SMichael Reifenberger  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2627aa4769SMichael Reifenberger  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2727aa4769SMichael Reifenberger  * SUCH DAMAGE.
2827aa4769SMichael Reifenberger  */
2927aa4769SMichael Reifenberger 
3027aa4769SMichael Reifenberger #include <sys/cdefs.h>
3127aa4769SMichael Reifenberger __FBSDID("$FreeBSD$");
3227aa4769SMichael Reifenberger 
3327aa4769SMichael Reifenberger #include <sys/types.h>
3427aa4769SMichael Reifenberger #include <sys/sysctl.h>
3527aa4769SMichael Reifenberger 
36*970bdbf5SMichael Tuexen #include <inttypes.h>
3727aa4769SMichael Reifenberger #include <string.h>
3827aa4769SMichael Reifenberger 
3927aa4769SMichael Reifenberger #include "systat.h"
4027aa4769SMichael Reifenberger #include "extern.h"
4127aa4769SMichael Reifenberger 
4227aa4769SMichael Reifenberger struct zfield{
4327aa4769SMichael Reifenberger 	uint64_t arcstats;
4427aa4769SMichael Reifenberger 	uint64_t arcstats_demand_data;
4527aa4769SMichael Reifenberger 	uint64_t arcstats_demand_metadata;
4627aa4769SMichael Reifenberger 	uint64_t arcstats_prefetch_data;
4727aa4769SMichael Reifenberger 	uint64_t arcstats_prefetch_metadata;
4827aa4769SMichael Reifenberger 	uint64_t zfetchstats;
4927aa4769SMichael Reifenberger 	uint64_t arcstats_l2;
5027aa4769SMichael Reifenberger 	uint64_t vdev_cache_stats;
5127aa4769SMichael Reifenberger };
5227aa4769SMichael Reifenberger 
5327aa4769SMichael Reifenberger static struct zarcstats {
5427aa4769SMichael Reifenberger 	struct zfield hits;
5527aa4769SMichael Reifenberger 	struct zfield misses;
5627aa4769SMichael Reifenberger } curstat, initstat, oldstat;
5727aa4769SMichael Reifenberger 
5827aa4769SMichael Reifenberger static void
5927aa4769SMichael Reifenberger getinfo(struct zarcstats *ls);
6027aa4769SMichael Reifenberger 
6127aa4769SMichael Reifenberger WINDOW *
6227aa4769SMichael Reifenberger openzarc(void)
6327aa4769SMichael Reifenberger {
6427aa4769SMichael Reifenberger 	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
6527aa4769SMichael Reifenberger }
6627aa4769SMichael Reifenberger 
6727aa4769SMichael Reifenberger void
6827aa4769SMichael Reifenberger closezarc(WINDOW *w)
6927aa4769SMichael Reifenberger {
7027aa4769SMichael Reifenberger 	if (w == NULL)
7127aa4769SMichael Reifenberger 		return;
7227aa4769SMichael Reifenberger 	wclear(w);
7327aa4769SMichael Reifenberger 	wrefresh(w);
7427aa4769SMichael Reifenberger 	delwin(w);
7527aa4769SMichael Reifenberger }
7627aa4769SMichael Reifenberger 
7727aa4769SMichael Reifenberger void
7827aa4769SMichael Reifenberger labelzarc(void)
7927aa4769SMichael Reifenberger {
8027aa4769SMichael Reifenberger 	wmove(wnd, 0, 0); wclrtoeol(wnd);
8127aa4769SMichael Reifenberger 	mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s",
8227aa4769SMichael Reifenberger 		"rate", "hits", "misses", "total hits", "total misses");
8327aa4769SMichael Reifenberger #define L(row, str) mvwprintw(wnd, row, 5, str); \
8427aa4769SMichael Reifenberger 	mvwprintw(wnd, row, 31, ":"); \
8527aa4769SMichael Reifenberger 	mvwprintw(wnd, row, 31+4, "%%")
8627aa4769SMichael Reifenberger 	L(1, "arcstats");
8727aa4769SMichael Reifenberger 	L(2, "arcstats.demand_data");
8827aa4769SMichael Reifenberger 	L(3, "arcstats.demand_metadata");
8927aa4769SMichael Reifenberger 	L(4, "arcstats.prefetch_data");
9027aa4769SMichael Reifenberger 	L(5, "arcstats.prefetch_metadata");
9127aa4769SMichael Reifenberger 	L(6, "zfetchstats");
9227aa4769SMichael Reifenberger 	L(7, "arcstats.l2");
9327aa4769SMichael Reifenberger 	L(8, "vdev_cache_stats");
9427aa4769SMichael Reifenberger #undef L
9527aa4769SMichael Reifenberger }
9627aa4769SMichael Reifenberger 
9727aa4769SMichael Reifenberger static int calc(uint64_t hits, uint64_t misses)
9827aa4769SMichael Reifenberger {
9927aa4769SMichael Reifenberger     if( hits )
10027aa4769SMichael Reifenberger 	return 100 * hits / ( hits + misses );
10127aa4769SMichael Reifenberger     else
10227aa4769SMichael Reifenberger 	return 0;
10327aa4769SMichael Reifenberger }
10427aa4769SMichael Reifenberger 
10527aa4769SMichael Reifenberger static void
10627aa4769SMichael Reifenberger domode(struct zarcstats *delta, struct zarcstats *rate)
10727aa4769SMichael Reifenberger {
10827aa4769SMichael Reifenberger #define DO(stat) \
10927aa4769SMichael Reifenberger 	delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \
11027aa4769SMichael Reifenberger 	delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \
11127aa4769SMichael Reifenberger 	rate->hits.stat = calc(delta->hits.stat, delta->misses.stat)
11227aa4769SMichael Reifenberger 	DO(arcstats);
11327aa4769SMichael Reifenberger 	DO(arcstats_demand_data);
11427aa4769SMichael Reifenberger 	DO(arcstats_demand_metadata);
11527aa4769SMichael Reifenberger 	DO(arcstats_prefetch_data);
11627aa4769SMichael Reifenberger 	DO(arcstats_prefetch_metadata);
11727aa4769SMichael Reifenberger 	DO(zfetchstats);
11827aa4769SMichael Reifenberger 	DO(arcstats_l2);
11927aa4769SMichael Reifenberger 	DO(vdev_cache_stats);
12027aa4769SMichael Reifenberger 	DO(arcstats);
12127aa4769SMichael Reifenberger 	DO(arcstats_demand_data);
12227aa4769SMichael Reifenberger 	DO(arcstats_demand_metadata);
12327aa4769SMichael Reifenberger 	DO(arcstats_prefetch_data);
12427aa4769SMichael Reifenberger 	DO(arcstats_prefetch_metadata);
12527aa4769SMichael Reifenberger 	DO(zfetchstats);
12627aa4769SMichael Reifenberger 	DO(arcstats_l2);
12727aa4769SMichael Reifenberger 	DO(vdev_cache_stats);
12827aa4769SMichael Reifenberger #undef DO
12927aa4769SMichael Reifenberger }
13027aa4769SMichael Reifenberger 
13127aa4769SMichael Reifenberger void
13227aa4769SMichael Reifenberger showzarc(void)
13327aa4769SMichael Reifenberger {
13427aa4769SMichael Reifenberger 	struct zarcstats delta, rate;
13527aa4769SMichael Reifenberger 
13627aa4769SMichael Reifenberger 	memset(&delta, 0, sizeof delta);
13727aa4769SMichael Reifenberger 	memset(&rate, 0, sizeof rate);
13827aa4769SMichael Reifenberger 
13927aa4769SMichael Reifenberger 	domode(&delta, &rate);
14027aa4769SMichael Reifenberger 
14127aa4769SMichael Reifenberger #define DO(stat, row, col, fmt) \
14227aa4769SMichael Reifenberger 	mvwprintw(wnd, row, col, fmt, stat)
143*970bdbf5SMichael Tuexen #define	R(row, stat) DO(rate.hits.stat, row, 31+1, "%3"PRIu64)
144*970bdbf5SMichael Tuexen #define	H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7"PRIu64); \
145*970bdbf5SMichael Tuexen 	DO(curstat.hits.stat, row, 31+1+5+8+8, "%12"PRIu64)
146*970bdbf5SMichael Tuexen #define	M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7"PRIu64); \
147*970bdbf5SMichael Tuexen 	DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12"PRIu64)
14827aa4769SMichael Reifenberger #define	E(row, stat) R(row, stat); H(row, stat); M(row, stat);
14927aa4769SMichael Reifenberger 	E(1, arcstats);
15027aa4769SMichael Reifenberger 	E(2, arcstats_demand_data);
15127aa4769SMichael Reifenberger 	E(3, arcstats_demand_metadata);
15227aa4769SMichael Reifenberger 	E(4, arcstats_prefetch_data);
15327aa4769SMichael Reifenberger 	E(5, arcstats_prefetch_metadata);
15427aa4769SMichael Reifenberger 	E(6, zfetchstats);
15527aa4769SMichael Reifenberger 	E(7, arcstats_l2);
15627aa4769SMichael Reifenberger 	E(8, vdev_cache_stats);
15727aa4769SMichael Reifenberger #undef DO
15827aa4769SMichael Reifenberger #undef E
15927aa4769SMichael Reifenberger #undef M
16027aa4769SMichael Reifenberger #undef H
16127aa4769SMichael Reifenberger #undef R
16227aa4769SMichael Reifenberger }
16327aa4769SMichael Reifenberger 
16427aa4769SMichael Reifenberger int
16527aa4769SMichael Reifenberger initzarc(void)
16627aa4769SMichael Reifenberger {
16727aa4769SMichael Reifenberger 	getinfo(&initstat);
16827aa4769SMichael Reifenberger 	curstat = oldstat = initstat;
16927aa4769SMichael Reifenberger 	return 1;
17027aa4769SMichael Reifenberger }
17127aa4769SMichael Reifenberger 
17227aa4769SMichael Reifenberger void
17327aa4769SMichael Reifenberger resetzarc(void)
17427aa4769SMichael Reifenberger {
17527aa4769SMichael Reifenberger 	initzarc();
17627aa4769SMichael Reifenberger }
17727aa4769SMichael Reifenberger 
17827aa4769SMichael Reifenberger static void
17927aa4769SMichael Reifenberger getinfo(struct zarcstats *ls)
18027aa4769SMichael Reifenberger {
18127aa4769SMichael Reifenberger 	size_t size = sizeof( ls->hits.arcstats );
18227aa4769SMichael Reifenberger 	if ( sysctlbyname("kstat.zfs.misc.arcstats.hits",
18327aa4769SMichael Reifenberger 		&ls->hits.arcstats, &size, NULL, 0 ) != 0 )
18427aa4769SMichael Reifenberger 		return;
18527aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.misses",
18627aa4769SMichael Reifenberger 		ls->misses.arcstats);
18727aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits",
18827aa4769SMichael Reifenberger 		ls->hits.arcstats_demand_data);
18927aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses",
19027aa4769SMichael Reifenberger 		ls->misses.arcstats_demand_data);
19127aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits",
19227aa4769SMichael Reifenberger 		ls->hits.arcstats_demand_metadata);
19327aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses",
19427aa4769SMichael Reifenberger 		ls->misses.arcstats_demand_metadata);
19527aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits",
19627aa4769SMichael Reifenberger 		ls->hits.arcstats_prefetch_data);
19727aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses",
19827aa4769SMichael Reifenberger 		ls->misses.arcstats_prefetch_data);
19927aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits",
20027aa4769SMichael Reifenberger 		ls->hits.arcstats_prefetch_metadata);
20127aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses",
20227aa4769SMichael Reifenberger 		ls->misses.arcstats_prefetch_metadata);
20327aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.zfetchstats.hits",
20427aa4769SMichael Reifenberger 		ls->hits.zfetchstats);
20527aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.zfetchstats.misses",
20627aa4769SMichael Reifenberger 		ls->misses.zfetchstats);
20727aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits",
20827aa4769SMichael Reifenberger 		ls->hits.arcstats_l2);
20927aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses",
21027aa4769SMichael Reifenberger 		ls->misses.arcstats_l2);
21127aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits",
21227aa4769SMichael Reifenberger 		ls->hits.vdev_cache_stats);
21327aa4769SMichael Reifenberger 	GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses",
21427aa4769SMichael Reifenberger 		ls->misses.vdev_cache_stats);
21527aa4769SMichael Reifenberger }
21627aa4769SMichael Reifenberger 
21727aa4769SMichael Reifenberger void
21827aa4769SMichael Reifenberger fetchzarc(void)
21927aa4769SMichael Reifenberger {
22027aa4769SMichael Reifenberger 	oldstat = curstat;
22127aa4769SMichael Reifenberger 	getinfo(&curstat);
22227aa4769SMichael Reifenberger }
223