blob: 6c61c22551eacd7fbb8226da2f6deba68c57cc9c [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 Gregg48fbc3e2015-08-18 14:56:14 -070044dist_max = 64
45
46# header
47print("Tracing... Hit Ctrl-C to end.")
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070048
49# functions
50stars_max = 38
51def stars(val, val_max, width):
52 i = 0
53 text = ""
54 while (1):
55 if (i > (width * val / val_max) - 1) or (i > width - 1):
56 break
57 text += "*"
58 i += 1
59 if val > val_max:
60 text = text[:-1] + "+"
61 return text
62
Brendan Gregg057b0782015-08-20 12:40:37 -070063def print_log2_hist(dist, val_type):
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070064 idx_max = -1
65 val_max = 0
66 for i in range(1, dist_max + 1):
67 try:
Brendan Greggef2452d2015-08-26 20:15:18 +100068 val = dist[c_int(i)].value
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070069 if (val > 0):
70 idx_max = i
71 if (val > val_max):
72 val_max = val
73 except:
74 break
75 if idx_max > 0:
76 print(" %-15s : count distribution" % val_type);
77 for i in range(1, idx_max + 1):
78 low = (1 << i) >> 1
79 high = (1 << i) - 1
80 if (low == high):
81 low -= 1
82 try:
Brendan Greggef2452d2015-08-26 20:15:18 +100083 val = dist[c_int(i)].value
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070084 print("%8d -> %-8d : %-8d |%-*s|" % (low, high, val,
85 stars_max, stars(val, val_max, stars_max)))
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070086 except:
87 break
88
89# output
90loop = 0
91do_exit = 0
92while (1):
93 if count > 0:
94 loop += 1
95 if loop > count:
96 exit()
97 try:
98 sleep(interval)
99 except KeyboardInterrupt:
100 pass; do_exit = 1
101
102 print
Brenden Blanco01ef55f2015-08-20 11:27:21 -0700103 print_log2_hist(b["dist"], "usecs")
Brendan Greggef2452d2015-08-26 20:15:18 +1000104 b["dist"].clear()
Brendan Gregg48fbc3e2015-08-18 14:56:14 -0700105 if do_exit:
106 exit()