blob: da6a0d4273ef17a52483637982cb13335bd189c9 [file] [log] [blame]
Brendan Greggebdb2422015-08-18 16:53:41 -07001#!/usr/bin/python
Brendan Gregg48fbc3e2015-08-18 14:56:14 -07002#
3# vfsreadlat.py VFS read latency distribution.
4# For Linux, uses BCC, eBPF. See .c file.
5#
6# Written as a basic example of a function latency distribution histogram.
7#
8# USAGE: vfsreadlat.py [interval [count]]
9#
10# The default interval is 5 seconds. A Ctrl-C will print the partially
11# gathered histogram then exit.
12#
13# Copyright (c) 2015 Brendan Gregg.
14# Licensed under the Apache License, Version 2.0 (the "License")
15#
16# 15-Aug-2015 Brendan Gregg Created this.
17
18from bpf import BPF
19from ctypes import c_ushort, c_int, c_ulonglong
20from time import sleep
21from sys import argv
22
23def usage():
24 print("USAGE: %s [interval [count]]" % argv[0])
25 exit()
26
27# arguments
28interval = 5
29count = -1
30if len(argv) > 1:
31 try:
32 interval = int(argv[1])
33 if interval == 0:
34 raise
35 if len(argv) > 2:
36 count = int(argv[2])
37 except: # also catches -h, --help
38 usage()
39
40# load BPF program
41b = BPF(src_file = "vfsreadlat.c")
Brenden Blanco5eef65e2015-08-19 15:39:19 -070042b.attach_kprobe(event="vfs_read", fn_name="do_entry")
43b.attach_kretprobe(event="vfs_read", fn_name="do_return")
Brendan Greggef4e1fc2015-08-18 15:34:56 -070044dist = b.get_table("dist")
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070045dist_max = 64
46
47# header
48print("Tracing... Hit Ctrl-C to end.")
49last = {}
50for i in range(1, dist_max + 1):
51 last[i] = 0
52
53# functions
54stars_max = 38
55def stars(val, val_max, width):
56 i = 0
57 text = ""
58 while (1):
59 if (i > (width * val / val_max) - 1) or (i > width - 1):
60 break
61 text += "*"
62 i += 1
63 if val > val_max:
64 text = text[:-1] + "+"
65 return text
66
67def print_log2_hist(d, val_type):
68 idx_max = -1
69 val_max = 0
70 for i in range(1, dist_max + 1):
71 try:
72 val = dist[c_int(i)].value - last[i]
73 if (val > 0):
74 idx_max = i
75 if (val > val_max):
76 val_max = val
77 except:
78 break
79 if idx_max > 0:
80 print(" %-15s : count distribution" % val_type);
81 for i in range(1, idx_max + 1):
82 low = (1 << i) >> 1
83 high = (1 << i) - 1
84 if (low == high):
85 low -= 1
86 try:
87 val = dist[c_int(i)].value - last[i]
88 print("%8d -> %-8d : %-8d |%-*s|" % (low, high, val,
89 stars_max, stars(val, val_max, stars_max)))
90 last[i] = dist[c_int(i)].value
91 except:
92 break
93
94# output
95loop = 0
96do_exit = 0
97while (1):
98 if count > 0:
99 loop += 1
100 if loop > count:
101 exit()
102 try:
103 sleep(interval)
104 except KeyboardInterrupt:
105 pass; do_exit = 1
106
107 print
108 print_log2_hist(dist, "usecs")
109 if do_exit:
110 exit()