Whamcloud - gitweb
LU-12461 contrib: Add epython scripts for crash dump analysis
[fs/lustre-release.git] / contrib / debug_tools / epython_scripts / rpc_stats.py
1 #!/usr/bin/env python
2
3 """
4 Copyright (c) 2015-2018 Cray Inc. All Rights Reserved.
5 Utility to display rpc stats for a client_obd
6 """
7
8 from pykdump.API import *
9 import argparse
10
11 import lustrelib as ll
12 from crashlib.input import toint
13
14 description_short = 'Dumps the rpc stats for a given client_obd'
15
16 OBD_HIST_MAX = 32
17
18 def get_cli_obd(client_obd):
19     cli = None
20     try:
21         cli = readSU('struct client_obd', client_obd)
22     except Exception, e:
23         for dev in readSymbol('obd_devs'):
24             try:
25                 if ll.obd2str(dev, 4) == client_obd:
26                     cli = dev.u.cli
27                     break
28             except Exception, e:
29                 continue
30     return cli
31
32 def pct(a, b):
33     return 100 * a / b if b else 0
34
35 def lprocfs_oh_sum(oh):
36     ret = 0
37     for i in range(OBD_HIST_MAX):
38         ret += oh.oh_buckets[i]
39     return ret
40
41 def osc_rpc_stats_seq_show(client_obd):
42     if not client_obd:
43         print "invalid input for field 'client_obd'"
44         return 1
45     cli = readSU('struct client_obd', client_obd)
46     print "read RPCs in flight:  %d" % cli.cl_r_in_flight
47     print "write RPCs in flight: %d" % cli.cl_w_in_flight
48     print "pending write pages:  %d" % cli.cl_pending_w_pages.counter
49     print "pending read pages:   %d" % cli.cl_pending_r_pages.counter
50
51     print "\n\t\t\tread\t\t\twrite"
52     print "pages per rpc         rpcs   % cum % |       rpcs   % cum %\n"
53
54     read_tot = lprocfs_oh_sum(cli.cl_read_page_hist)
55     write_tot = lprocfs_oh_sum(cli.cl_write_page_hist)
56
57     read_cum = 0
58     write_cum = 0
59     for i in range(OBD_HIST_MAX):
60         r = cli.cl_read_page_hist.oh_buckets[i]
61         w = cli.cl_write_page_hist.oh_buckets[i]
62
63         read_cum += r
64         write_cum += w
65         print "%d:\t\t%10d %3d %3d   | %10d %3d %3d" % \
66               (1 << i, r, pct(r, read_tot),
67               pct(read_cum, read_tot), w,
68               pct(w, write_tot),
69               pct(write_cum, write_tot))
70         if read_cum == read_tot and write_cum == write_tot:
71             break
72
73     print "\n\t\t\tread\t\t\twrite"
74     print "rpcs in flight        rpcs   % cum % |       rpcs   % cum %\n"
75
76     read_tot = lprocfs_oh_sum(cli.cl_read_rpc_hist)
77     write_tot = lprocfs_oh_sum(cli.cl_write_rpc_hist)
78
79     read_cum = 0
80     write_cum = 0
81     for i in range(OBD_HIST_MAX):
82         r = cli.cl_read_rpc_hist.oh_buckets[i]
83         w = cli.cl_write_rpc_hist.oh_buckets[i]
84
85         read_cum += r
86         write_cum += w
87         print "%d:\t\t%10d %3d %3d   | %10d %3d %3d" % \
88               (i, r, pct(r, read_tot),
89               pct(read_cum, read_tot), w,
90               pct(w, write_tot),
91               pct(write_cum, write_tot))
92         if read_cum == read_tot and write_cum == write_tot:
93             break
94
95     print "\n\t\t\tread\t\t\twrite"
96     print "offset                rpcs   % cum % |       rpcs   % cum %\n"
97
98     read_tot = lprocfs_oh_sum(cli.cl_read_offset_hist)
99     write_tot = lprocfs_oh_sum(cli.cl_write_offset_hist)
100
101     read_cum = 0
102     write_cum = 0
103     for i in range(OBD_HIST_MAX):
104         r = cli.cl_read_offset_hist.oh_buckets[i]
105         w = cli.cl_write_offset_hist.oh_buckets[i]
106
107         read_cum += r
108         write_cum += w
109         offset = 0 if i == 0 else 1 << (i - 1)
110         print "%d:      \t%10d %3d %3d   | %10d %3d %3d" % \
111               (offset, r, pct(r, read_tot),
112               pct(read_cum, read_tot), w,
113               pct(w, write_tot),
114               pct(write_cum, write_tot))
115         if read_cum == read_tot and write_cum == write_tot:
116             break
117     print
118     return 0
119
120 if __name__ == "__main__":
121     parser = argparse.ArgumentParser(description=description_short)
122     parser.add_argument("client_obd", nargs="?", default=[], type=toint,
123         help="address of client_obd structure whose stats will be dumped")
124     args = parser.parse_args()
125     cli = get_cli_obd(args.client_obd)
126     osc_rpc_stats_seq_show(cli)