From 07d6440156f8861efb8434a9248a6f7441d8ecc3 Mon Sep 17 00:00:00 2001 From: Ameer Hamza Date: Mon, 15 Apr 2024 21:23:22 +0500 Subject: [PATCH] Add zfetch stats in arcstats arc_summary also reports zfetch stats but it's inconvenient to monitor contiguously incrementing numbers. Adding them in arcstats allows us to observe streams more conveniently. Signed-off-by: Ameer Hamza --- cmd/arcstat.in | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/cmd/arcstat.in b/cmd/arcstat.in index 8df1c62f7e8..2d4dc9ca433 100755 --- a/cmd/arcstat.in +++ b/cmd/arcstat.in @@ -157,6 +157,15 @@ cols = { "free": [5, 1024, "ARC free memory"], "avail": [5, 1024, "ARC available memory"], "waste": [5, 1024, "Wasted memory due to round up to pagesize"], + "ztotal": [6, 1024, "zfetch total prefetcher calls per second"], + "zhits": [5, 1024, "zfetch stream hits per second"], + "zfuture": [7, 1024, "zfetch hits ahead of streams per second"], + "zpast": [5, 1024, "zfetch hits behind streams per second"], + "zmisses": [7, 1024, "zfetch stream misses per second"], + "zmax": [4, 1024, "zfetch limit reached per second"], + "zstride": [7, 1024, "zfetch stream strides per second"], + "zissued": [7, 1024, "zfetch prefetches issued per second"], + "zactive": [7, 1024, "zfetch prefetches active per second"], } v = {} @@ -164,6 +173,8 @@ hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%", "size", "c", "avail"] xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis", "dread", "pread", "read"] +zhdr = ["time", "ztotal", "zhits", "zfuture", "zpast", "zmisses", "zmax", + "zstride", "zissued", "zactive"] sint = 1 # Default interval is 1 second count = 1 # Default count is 1 hdr_intr = 20 # Print header every 20 lines of output @@ -206,12 +217,21 @@ elif sys.platform.startswith('linux'): def kstat_update(): global kstat - k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] + k1 = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] - if not k: + k2 = [line.strip().replace('hits', 'stream_hits') + .replace('future','stream_future') + .replace('past','stream_past') + .replace('stride','stream_stride') + .replace('misses','stream_misses') + for line in open('/proc/spl/kstat/zfs/zfetchstats')] + + if k1 is None or k2 is None: sys.exit(1) - del k[0:2] + del k1[0:2] + del k2[0:2] + k = k1 + k2 kstat = {} for s in k: @@ -239,6 +259,7 @@ def usage(): sys.stderr.write("\t -v : List all possible field headers and definitions" "\n") sys.stderr.write("\t -x : Print extended stats\n") + sys.stderr.write("\t -z : Print zfetch stats\n") sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n") sys.stderr.write("\t -o : Redirect output to the specified file\n") sys.stderr.write("\t -s : Override default field separator with custom " @@ -357,6 +378,7 @@ def init(): global count global hdr global xhdr + global zhdr global opfile global sep global out @@ -368,15 +390,17 @@ def init(): xflag = False hflag = False vflag = False + zflag = False i = 1 try: opts, args = getopt.getopt( sys.argv[1:], - "axo:hvs:f:p", + "axzo:hvs:f:p", [ "all", "extended", + "zfetch", "outfile", "help", "verbose", @@ -410,13 +434,15 @@ def init(): i += 1 if opt in ('-p', '--parsable'): pretty_print = False + if opt in ('-z', '--zfetch'): + zflag = True i += 1 argv = sys.argv[i:] sint = int(argv[0]) if argv else sint count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1) - if hflag or (xflag and desired_cols): + if hflag or (xflag and zflag) or ((zflag or xflag) and desired_cols): usage() if vflag: @@ -425,6 +451,9 @@ def init(): if xflag: hdr = xhdr + if zflag: + hdr = zhdr + update_hdr_intr() # check if L2ARC exists @@ -569,6 +598,16 @@ def calculate(): v["el2mru"] = d["evict_l2_eligible_mru"] // sint v["el2inel"] = d["evict_l2_ineligible"] // sint v["mtxmis"] = d["mutex_miss"] // sint + v["ztotal"] = (d["stream_hits"] + d["stream_future"] + d["stream_stride"] + + d["stream_past"] + d["stream_misses"]) // sint + v["zhits"] = d["stream_hits"] // sint + v["zfuture"] = (d["stream_future"] + d["stream_stride"]) // sint + v["zpast"] = d["stream_past"] // sint + v["zmisses"] = d["stream_misses"] // sint + v["zmax"] = d["max_streams"] // sint + v["zstride"] = d["stream_stride"] // sint + v["zissued"] = d["io_issued"] // sint + v["zactive"] = d["io_active"] // sint if l2exist: v["l2hits"] = d["l2_hits"] // sint