Index: contrib/top/top.c =================================================================== --- contrib/top/top.c (revision 225580) +++ contrib/top/top.c (working copy) @@ -122,6 +122,8 @@ int u_cpustates(); int i_memory(); int u_memory(); +int i_arc(); +int u_arc(); int i_swap(); int u_swap(); int i_message(); @@ -136,6 +138,7 @@ int (*d_procstates)() = i_procstates; int (*d_cpustates)() = i_cpustates; int (*d_memory)() = i_memory; +int (*d_arc)() = i_arc; int (*d_swap)() = i_swap; int (*d_message)() = i_message; int (*d_header)() = i_header; @@ -648,6 +651,7 @@ /* display memory stats */ (*d_memory)(system_info.memory); + (*d_arc)(system_info.arc); /* display swap stats */ (*d_swap)(system_info.swap); @@ -713,6 +717,7 @@ d_procstates = u_procstates; d_cpustates = u_cpustates; d_memory = u_memory; + d_arc = u_arc; d_swap = u_swap; d_message = u_message; d_header = u_header; @@ -1131,6 +1136,7 @@ d_procstates = i_procstates; d_cpustates = i_cpustates; d_memory = i_memory; + d_arc = i_arc; d_swap = i_swap; d_message = i_message; d_header = i_header; Index: contrib/top/display.c =================================================================== --- contrib/top/display.c (revision 225580) +++ contrib/top/display.c (working copy) @@ -66,6 +66,7 @@ static char **procstate_names; static char **cpustate_names; static char **memory_names; +static char **arc_names; static char **swap_names; static int num_procstates; @@ -100,6 +101,8 @@ int y_brkdn = 1; int x_mem = 5; int y_mem = 3; +int x_arc = 5; +int y_arc = 4; int x_swap = 6; int y_swap = 4; int y_message = 5; @@ -216,6 +219,8 @@ num_memory = string_count(memory_names); lmemory = (int *)malloc(num_memory * sizeof(int)); + arc_names = statics->arc_names; + /* calculate starting columns where needed */ cpustate_total_length = 0; pp = cpustate_names; @@ -627,6 +632,46 @@ } /* + * *_arc(stats) - print "ARC: " followed by the ARC summary string + * + * Assumptions: cursor is on "lastline" + * for i_arc ONLY: cursor is on the previous line + */ +char arc_buffer[MAX_COLS]; + +i_arc(stats) + +int *stats; + +{ + if (arc_names == NULL) + return (0); + + fputs("\nARC: ", stdout); + lastline++; + + /* format and print the memory summary */ + summary_format(arc_buffer, stats, arc_names); + fputs(arc_buffer, stdout); +} + +u_arc(stats) + +int *stats; + +{ + static char new[MAX_COLS]; + + if (arc_names == NULL) + return (0); + + /* format the new line */ + summary_format(new, stats, arc_names); + line_update(arc_buffer, new, x_arc, y_arc); +} + + +/* * *_swap(stats) - print "Swap: " followed by the swap summary string * * Assumptions: cursor is on "lastline" Index: contrib/top/machine.h =================================================================== --- contrib/top/machine.h (revision 225580) +++ contrib/top/machine.h (working copy) @@ -16,6 +16,7 @@ char **procstate_names; char **cpustate_names; char **memory_names; + char **arc_names; char **swap_names; #ifdef ORDER char **order_names; @@ -42,6 +43,7 @@ int *procstates; int *cpustates; int *memory; + int *arc; int *swap; struct timeval boottime; int ncpus; Index: contrib/top/layout.h =================================================================== --- contrib/top/layout.h (revision 225580) +++ contrib/top/layout.h (working copy) @@ -19,6 +19,8 @@ extern int y_brkdn; /* 1 */ extern int x_mem; /* 5 */ extern int y_mem; /* 3 */ +extern int x_arc; /* 5 */ +extern int y_arc; /* 4 */ extern int x_swap; /* 6 */ extern int y_swap; /* 4 */ extern int y_message; /* 5 */ Index: usr.bin/top/machine.c =================================================================== --- usr.bin/top/machine.c (revision 225580) +++ usr.bin/top/machine.c (working copy) @@ -176,6 +176,12 @@ "K Free", NULL }; +int arc_stats[7]; +char *arcnames[] = { + "K Total, ", "K MRU, ", "K MFU, ", "K Anon, ", "K Header, ", "K Other", + NULL +}; + int swap_stats[7]; char *swapnames[] = { "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out", @@ -194,6 +200,7 @@ static struct kinfo_proc **previous_pref; static int previous_proc_count = 0; static int previous_proc_count_max = 0; +static int arc_enabled; /* total number of io operations */ static long total_inblock; @@ -239,31 +246,38 @@ static const char *format_nice(const struct kinfo_proc *pp); static void getsysctl(const char *name, void *ptr, size_t len); static int swapmode(int *retavail, int *retfree); - +static void update_layout(void); + void toggle_pcpustats(void) { if (ncpus == 1) return; + update_layout(); +} - /* Adjust display based on ncpus */ +static void +update_layout(void) +{ + + y_mem = 3; + y_swap = 4 + arc_enabled; + y_idlecursor = 5 + arc_enabled; + y_message = 5 + arc_enabled; + y_header = 6 + arc_enabled; + y_procs = 7 + arc_enabled; + Header_lines = 7 + arc_enabled; + + /* Adjust display based on ncpus and the ARC state. */ if (pcpu_stats) { - y_mem += ncpus - 1; /* 3 */ - y_swap += ncpus - 1; /* 4 */ - y_idlecursor += ncpus - 1; /* 5 */ - y_message += ncpus - 1; /* 5 */ - y_header += ncpus - 1; /* 6 */ - y_procs += ncpus - 1; /* 7 */ - Header_lines += ncpus - 1; /* 7 */ - } else { - y_mem = 3; - y_swap = 4; - y_idlecursor = 5; - y_message = 5; - y_header = 6; - y_procs = 7; - Header_lines = 7; + y_mem = ncpus - 1; + y_swap += ncpus - 1; + y_idlecursor += ncpus - 1; + y_message += ncpus - 1; + y_header += ncpus - 1; + y_procs += ncpus - 1; + Header_lines += ncpus - 1; } } @@ -271,6 +285,7 @@ machine_init(struct statics *statics, char do_unames) { int i, j, empty, pagesize; + uint64_t arc_size; size_t size; struct passwd *pw; @@ -282,6 +297,11 @@ size != sizeof(smpmode)) smpmode = 0; + size = sizeof(arc_size); + if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arc_size, &size, + NULL, 0) == 0 && arc_size != 0) + arc_enabled = 1; + if (do_unames) { while ((pw = getpwent()) != NULL) { if (strlen(pw->pw_name) > namelength) @@ -322,6 +342,10 @@ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; + if (arc_enabled) + statics->arc_names = arcnames; + else + statics->arc_names = NULL; statics->swap_names = swapnames; #ifdef ORDER statics->order_names = ordernames; @@ -356,8 +380,7 @@ pcpu_cpu_states = calloc(1, size); statics->ncpus = ncpus; - if (pcpu_stats) - toggle_pcpustats(); + update_layout(); /* all done! */ return (0); @@ -408,7 +431,7 @@ struct loadavg sysload; int mib[2]; struct timeval boottime; - size_t bt_size; + uint64_t arc_stat, arc_stat2; int i, j; size_t size; @@ -487,6 +510,23 @@ swap_stats[6] = -1; } + if (arc_enabled) { + GETSYSCTL("kstat.zfs.misc.arcstats.size", arc_stat); + arc_stats[0] = arc_stat >> 10; + GETSYSCTL("vfs.zfs.mfu_size", arc_stat); + arc_stats[1] = arc_stat >> 10; + GETSYSCTL("vfs.zfs.mru_size", arc_stat); + arc_stats[2] = arc_stat >> 10; + GETSYSCTL("vfs.zfs.anon_size", arc_stat); + arc_stats[3] = arc_stat >> 10; + GETSYSCTL("kstat.zfs.misc.arcstats.hdr_size", arc_stat); + GETSYSCTL("kstat.zfs.misc.arcstats.l2_hdr_size", arc_stat2); + arc_stats[4] = arc_stat + arc_stat2 >> 10; + GETSYSCTL("kstat.zfs.misc.arcstats.other_size", arc_stat); + arc_stats[5] = arc_stat >> 10; + si->arc = arc_stats; + } + /* set arrays and strings */ if (pcpu_stats) { si->cpustates = pcpu_cpu_states; @@ -511,8 +551,8 @@ */ mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; - bt_size = sizeof(boottime); - if (sysctl(mib, 2, &boottime, &bt_size, NULL, 0) != -1 && + size = sizeof(boottime); + if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) { si->boottime = boottime; } else { Index: usr.bin/top/top.local.1 =================================================================== --- usr.bin/top/top.local.1 (revision 225580) +++ usr.bin/top/top.local.1 (working copy) @@ -3,6 +3,7 @@ .SH DESCRIPTION OF MEMORY Mem: 9220K Active, 1M Inact, 3284K Wired, 1M Cache, 2M Buf, 1320K Free +ARC: 2048K Total, 342K MRU, 760K MFU, 272K Anon, 232K Header, 442K Other Swap: 91M Total, 79M Free, 13% Inuse, 80K In, 104K Out .TP .B K: @@ -16,6 +17,7 @@ .TP .B %: 1/100 +.SS Physical Memory Stats .TP .B Active: number of bytes active @@ -24,7 +26,7 @@ number of bytes inactive .TP .B Wired: -number of bytes wired down, including cached file data pages +number of bytes wired down, including BIO-level cached file data pages .TP .B Cache: number of clean bytes caching data that are available for @@ -35,7 +37,28 @@ .TP .B Free: number of bytes free +.SS ZFS ARC Stats +These stats are only displayed when the ARC is in use. .TP +.B Total: +number of wired bytes used for the ZFS ARC +.TP +.B MRU: +number of ARC bytes holding most recently used data +.TP +.B MFU: +number of ARC bytes holding most frequently used data +.TP +.B Anon: +number of ARC bytes holding in flight data +.TP +.B Header: +number of ARC bytes holding headers +.TP +.B Other +miscellaneous ARC bytes +.SS Swap Stats +.TP .B Total: total available swap usage .TP