aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2012-06-27 18:08:48 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2012-06-27 18:08:48 +0000
commit2e52fb92ff82120099f4358b47ce51a2b62fda17 (patch)
tree35d3ccc9768fc207017486150335cd6c1e66bfc4
parent50a994c98b963bfe339e0516b1d75ede86c7c5d4 (diff)
downloadsrc-2e52fb92ff82120099f4358b47ce51a2b62fda17.tar.gz
src-2e52fb92ff82120099f4358b47ce51a2b62fda17.zip
Add a new line to top that provides a brief summary of the ZFS ARC memory
usage on hosts using ZFS. The new line displays the total amount of RAM used by the ARC along with the size of MFU, MRU, anonymous (in flight), headers, and other (miscellaneous) sub-categories. The line is not displayed on systems that are not using ZFS. Reviewed by: avg, fs@ MFC after: 3 days
Notes
Notes: svn path=/head/; revision=237656
-rw-r--r--contrib/top/display.c45
-rw-r--r--contrib/top/layout.h2
-rw-r--r--contrib/top/machine.h2
-rw-r--r--contrib/top/top.c6
-rw-r--r--usr.bin/top/machine.c82
-rw-r--r--usr.bin/top/top.local.123
6 files changed, 139 insertions, 21 deletions
diff --git a/contrib/top/display.c b/contrib/top/display.c
index 89795c05e4da..e65ae24f528f 100644
--- a/contrib/top/display.c
+++ b/contrib/top/display.c
@@ -66,6 +66,7 @@ char *screenbuf = NULL;
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 x_brkdn = 15;
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 @@ struct statics *statics;
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 @@ int *stats;
}
/*
+ * *_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"
diff --git a/contrib/top/layout.h b/contrib/top/layout.h
index 1b2564e0a657..a04fce215b07 100644
--- a/contrib/top/layout.h
+++ b/contrib/top/layout.h
@@ -19,6 +19,8 @@ extern int x_brkdn; /* 15 */
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 */
diff --git a/contrib/top/machine.h b/contrib/top/machine.h
index 3e1af1609ece..699c7554df05 100644
--- a/contrib/top/machine.h
+++ b/contrib/top/machine.h
@@ -16,6 +16,7 @@ struct statics
char **procstate_names;
char **cpustate_names;
char **memory_names;
+ char **arc_names;
char **swap_names;
#ifdef ORDER
char **order_names;
@@ -42,6 +43,7 @@ struct system_info
int *procstates;
int *cpustates;
int *memory;
+ int *arc;
int *swap;
struct timeval boottime;
int ncpus;
diff --git a/contrib/top/top.c b/contrib/top/top.c
index 50bc9b967b5f..c2eb35da1a99 100644
--- a/contrib/top/top.c
+++ b/contrib/top/top.c
@@ -121,6 +121,8 @@ int i_cpustates();
int u_cpustates();
int i_memory();
int u_memory();
+int i_arc();
+int u_arc();
int i_swap();
int u_swap();
int i_message();
@@ -135,6 +137,7 @@ int (*d_loadave)() = i_loadave;
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;
@@ -647,6 +650,7 @@ restart:
/* display memory stats */
(*d_memory)(system_info.memory);
+ (*d_arc)(system_info.arc);
/* display swap stats */
(*d_swap)(system_info.swap);
@@ -712,6 +716,7 @@ restart:
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;
@@ -1129,6 +1134,7 @@ reset_display()
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;
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index 59f663da2a34..1d6b90719bf7 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -176,6 +176,12 @@ char *memorynames[] = {
"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_procs;
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,6 +246,7 @@ static int compare_tid(const void *a, const void *b);
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)
@@ -246,24 +254,30 @@ toggle_pcpustats(void)
if (ncpus == 1)
return;
+ update_layout();
+}
+
+/* Adjust display based on ncpus and the ARC state. */
+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 */
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 @@ int
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 @@ machine_init(struct statics *statics, char do_unames)
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 @@ machine_init(struct statics *statics, char do_unames)
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 @@ machine_init(struct statics *statics, char do_unames)
pcpu_cpu_states = calloc(1, size);
statics->ncpus = ncpus;
- if (pcpu_stats)
- toggle_pcpustats();
+ update_layout();
/* all done! */
return (0);
@@ -408,7 +431,7 @@ get_system_info(struct system_info *si)
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 @@ get_system_info(struct system_info *si)
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 @@ get_system_info(struct system_info *si)
*/
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 {
diff --git a/usr.bin/top/top.local.1 b/usr.bin/top/top.local.1
index a674828b829b..864ab8d65c4b 100644
--- a/usr.bin/top/top.local.1
+++ b/usr.bin/top/top.local.1
@@ -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 @@ Gigabyte
.TP
.B %:
1/100
+.SS Physical Memory Stats
.TP
.B Active:
number of bytes active
@@ -35,6 +37,27 @@ number of bytes used for BIO-level disk caching
.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