diff options
Diffstat (limited to 'tools/perf/scripts/perl/rwtop.pl')
-rw-r--r-- | tools/perf/scripts/perl/rwtop.pl | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl new file mode 100644 index 000000000000..4bb3ecd33472 --- /dev/null +++ b/tools/perf/scripts/perl/rwtop.pl | |||
@@ -0,0 +1,199 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
3 | # Licensed under the terms of the GNU GPL License version 2 | ||
4 | |||
5 | # read/write top | ||
6 | # | ||
7 | # Periodically displays system-wide r/w call activity, broken down by | ||
8 | # pid. If an [interval] arg is specified, the display will be | ||
9 | # refreshed every [interval] seconds. The default interval is 3 | ||
10 | # seconds. | ||
11 | |||
12 | use 5.010000; | ||
13 | use strict; | ||
14 | use warnings; | ||
15 | |||
16 | use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; | ||
17 | use lib "./Perf-Trace-Util/lib"; | ||
18 | use Perf::Trace::Core; | ||
19 | use Perf::Trace::Util; | ||
20 | |||
21 | my $default_interval = 3; | ||
22 | my $nlines = 20; | ||
23 | my $print_thread; | ||
24 | my $print_pending = 0; | ||
25 | |||
26 | my %reads; | ||
27 | my %writes; | ||
28 | |||
29 | my $interval = shift; | ||
30 | if (!$interval) { | ||
31 | $interval = $default_interval; | ||
32 | } | ||
33 | |||
34 | sub syscalls::sys_exit_read | ||
35 | { | ||
36 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
37 | $common_pid, $common_comm, | ||
38 | $nr, $ret) = @_; | ||
39 | |||
40 | print_check(); | ||
41 | |||
42 | if ($ret > 0) { | ||
43 | $reads{$common_pid}{bytes_read} += $ret; | ||
44 | } else { | ||
45 | if (!defined ($reads{$common_pid}{bytes_read})) { | ||
46 | $reads{$common_pid}{bytes_read} = 0; | ||
47 | } | ||
48 | $reads{$common_pid}{errors}{$ret}++; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | sub syscalls::sys_enter_read | ||
53 | { | ||
54 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
55 | $common_pid, $common_comm, | ||
56 | $nr, $fd, $buf, $count) = @_; | ||
57 | |||
58 | print_check(); | ||
59 | |||
60 | $reads{$common_pid}{bytes_requested} += $count; | ||
61 | $reads{$common_pid}{total_reads}++; | ||
62 | $reads{$common_pid}{comm} = $common_comm; | ||
63 | } | ||
64 | |||
65 | sub syscalls::sys_exit_write | ||
66 | { | ||
67 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
68 | $common_pid, $common_comm, | ||
69 | $nr, $ret) = @_; | ||
70 | |||
71 | print_check(); | ||
72 | |||
73 | if ($ret <= 0) { | ||
74 | $writes{$common_pid}{errors}{$ret}++; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | sub syscalls::sys_enter_write | ||
79 | { | ||
80 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
81 | $common_pid, $common_comm, | ||
82 | $nr, $fd, $buf, $count) = @_; | ||
83 | |||
84 | print_check(); | ||
85 | |||
86 | $writes{$common_pid}{bytes_written} += $count; | ||
87 | $writes{$common_pid}{total_writes}++; | ||
88 | $writes{$common_pid}{comm} = $common_comm; | ||
89 | } | ||
90 | |||
91 | sub trace_begin | ||
92 | { | ||
93 | $SIG{ALRM} = \&set_print_pending; | ||
94 | alarm 1; | ||
95 | } | ||
96 | |||
97 | sub trace_end | ||
98 | { | ||
99 | print_unhandled(); | ||
100 | print_totals(); | ||
101 | } | ||
102 | |||
103 | sub print_check() | ||
104 | { | ||
105 | if ($print_pending == 1) { | ||
106 | $print_pending = 0; | ||
107 | print_totals(); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | sub set_print_pending() | ||
112 | { | ||
113 | $print_pending = 1; | ||
114 | alarm $interval; | ||
115 | } | ||
116 | |||
117 | sub print_totals | ||
118 | { | ||
119 | my $count; | ||
120 | |||
121 | $count = 0; | ||
122 | |||
123 | clear_term(); | ||
124 | |||
125 | printf("\nread counts by pid:\n\n"); | ||
126 | |||
127 | printf("%6s %20s %10s %10s %10s\n", "pid", "comm", | ||
128 | "# reads", "bytes_req", "bytes_read"); | ||
129 | printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------", | ||
130 | "----------", "----------", "----------"); | ||
131 | |||
132 | foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=> | ||
133 | ($reads{$a}{bytes_read} || 0) } keys %reads) { | ||
134 | my $comm = $reads{$pid}{comm} || ""; | ||
135 | my $total_reads = $reads{$pid}{total_reads} || 0; | ||
136 | my $bytes_requested = $reads{$pid}{bytes_requested} || 0; | ||
137 | my $bytes_read = $reads{$pid}{bytes_read} || 0; | ||
138 | |||
139 | printf("%6s %-20s %10s %10s %10s\n", $pid, $comm, | ||
140 | $total_reads, $bytes_requested, $bytes_read); | ||
141 | |||
142 | if (++$count == $nlines) { | ||
143 | last; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | $count = 0; | ||
148 | |||
149 | printf("\nwrite counts by pid:\n\n"); | ||
150 | |||
151 | printf("%6s %20s %10s %13s\n", "pid", "comm", | ||
152 | "# writes", "bytes_written"); | ||
153 | printf("%6s %-20s %10s %13s\n", "------", "--------------------", | ||
154 | "----------", "-------------"); | ||
155 | |||
156 | foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=> | ||
157 | ($writes{$a}{bytes_written} || 0)} keys %writes) { | ||
158 | my $comm = $writes{$pid}{comm} || ""; | ||
159 | my $total_writes = $writes{$pid}{total_writes} || 0; | ||
160 | my $bytes_written = $writes{$pid}{bytes_written} || 0; | ||
161 | |||
162 | printf("%6s %-20s %10s %13s\n", $pid, $comm, | ||
163 | $total_writes, $bytes_written); | ||
164 | |||
165 | if (++$count == $nlines) { | ||
166 | last; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | %reads = (); | ||
171 | %writes = (); | ||
172 | } | ||
173 | |||
174 | my %unhandled; | ||
175 | |||
176 | sub print_unhandled | ||
177 | { | ||
178 | if ((scalar keys %unhandled) == 0) { | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | print "\nunhandled events:\n\n"; | ||
183 | |||
184 | printf("%-40s %10s\n", "event", "count"); | ||
185 | printf("%-40s %10s\n", "----------------------------------------", | ||
186 | "-----------"); | ||
187 | |||
188 | foreach my $event_name (keys %unhandled) { | ||
189 | printf("%-40s %10d\n", $event_name, $unhandled{$event_name}); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | sub trace_unhandled | ||
194 | { | ||
195 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
196 | $common_pid, $common_comm) = @_; | ||
197 | |||
198 | $unhandled{$event_name}++; | ||
199 | } | ||