aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/perl
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2010-04-02 00:59:23 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-14 05:56:08 -0400
commit47902f3611b392209e2a412bf7ec02dca95e666d (patch)
tree9fa26305e87a6f6354b3461067967b908a1d0a08 /tools/perf/scripts/perl
parentc7929e4727e8ff2d6fc8327188820e3b1c2f1dc3 (diff)
perf trace/scripting: Add rwtop and sctop scripts
A couple of scripts, one in Python and the other in Perl, that demonstrate 'live mode' tracing. For each, the output of the perf event stream is fed continuously to the script, which continuously aggregates the data and reports the current results every 3 seconds, or at the optionally specified interval. After the current results are displayed, the aggregations are cleared and the cycle begins anew. To run the scripts, simply pipe the output of the 'perf trace record' step as input to the corresponding 'perf trace report' step, using '-' as the filename to -o and -i: $ perf trace record sctop -o - | perf trace report sctop -i - Also adds clear_term() utility functions to the Util.pm and Util.py utility modules, for use by any script to clear the screen. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org Cc: k-keiichi@bx.jp.nec.com Cc: acme@ghostprotocols.net LKML-Reference: <1270184365-8281-10-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/scripts/perl')
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm6
-rw-r--r--tools/perf/scripts/perl/bin/rwtop-record2
-rw-r--r--tools/perf/scripts/perl/bin/rwtop-report23
-rw-r--r--tools/perf/scripts/perl/rwtop.pl177
4 files changed, 208 insertions, 0 deletions
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
index f869c48dc9b0..d94b40c8ac85 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
@@ -15,6 +15,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
15 15
16our @EXPORT = qw( 16our @EXPORT = qw(
17avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs 17avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
18clear_term
18); 19);
19 20
20our $VERSION = '0.01'; 21our $VERSION = '0.01';
@@ -55,6 +56,11 @@ sub nsecs_str {
55 return $str; 56 return $str;
56} 57}
57 58
59sub clear_term
60{
61 print "\x1b[H\x1b[2J";
62}
63
581; 641;
59__END__ 65__END__
60=head1 NAME 66=head1 NAME
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record
new file mode 100644
index 000000000000..63976bf11e8b
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rwtop-record
@@ -0,0 +1,2 @@
1#!/bin/bash
2perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
diff --git a/tools/perf/scripts/perl/bin/rwtop-report b/tools/perf/scripts/perl/bin/rwtop-report
new file mode 100644
index 000000000000..93e698cd3f38
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/rwtop-report
@@ -0,0 +1,23 @@
1#!/bin/bash
2# description: system-wide r/w top
3# args: [interval]
4n_args=0
5for i in "$@"
6do
7 if expr match "$i" "-" > /dev/null ; then
8 break
9 fi
10 n_args=$(( $n_args + 1 ))
11done
12if [ "$n_args" -gt 1 ] ; then
13 echo "usage: rwtop-report [interval]"
14 exit
15fi
16if [ "$n_args" -gt 0 ] ; then
17 interval=$1
18 shift
19fi
20perf trace $@ -s ~/libexec/perf-core/scripts/perl/rwtop.pl $interval
21
22
23
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl
new file mode 100644
index 000000000000..ec2ab49a6f25
--- /dev/null
+++ b/tools/perf/scripts/perl/rwtop.pl
@@ -0,0 +1,177 @@
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
12use 5.010000;
13use strict;
14use warnings;
15
16use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
17use lib "./Perf-Trace-Util/lib";
18use Perf::Trace::Core;
19use Perf::Trace::Util;
20
21my $default_interval = 3;
22my $nlines = 20;
23my $print_thread;
24
25my %reads;
26my %writes;
27
28my $interval = shift;
29if (!$interval) {
30 $interval = $default_interval;
31}
32
33sub syscalls::sys_exit_read
34{
35 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
36 $common_pid, $common_comm,
37 $nr, $ret) = @_;
38
39 if ($ret > 0) {
40 $reads{$common_pid}{bytes_read} += $ret;
41 } else {
42 if (!defined ($reads{$common_pid}{bytes_read})) {
43 $reads{$common_pid}{bytes_read} = 0;
44 }
45 $reads{$common_pid}{errors}{$ret}++;
46 }
47}
48
49sub syscalls::sys_enter_read
50{
51 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
52 $common_pid, $common_comm,
53 $nr, $fd, $buf, $count) = @_;
54
55 $reads{$common_pid}{bytes_requested} += $count;
56 $reads{$common_pid}{total_reads}++;
57 $reads{$common_pid}{comm} = $common_comm;
58}
59
60sub syscalls::sys_exit_write
61{
62 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
63 $common_pid, $common_comm,
64 $nr, $ret) = @_;
65
66 if ($ret <= 0) {
67 $writes{$common_pid}{errors}{$ret}++;
68 }
69}
70
71sub syscalls::sys_enter_write
72{
73 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
74 $common_pid, $common_comm,
75 $nr, $fd, $buf, $count) = @_;
76
77 $writes{$common_pid}{bytes_written} += $count;
78 $writes{$common_pid}{total_writes}++;
79 $writes{$common_pid}{comm} = $common_comm;
80}
81
82sub trace_begin
83{
84 $SIG{ALRM} = \&print_totals;
85 alarm 1;
86}
87
88sub trace_end
89{
90 print_unhandled();
91 print_totals();
92}
93
94sub print_totals
95{
96 my $count;
97
98 $count = 0;
99
100 clear_term();
101
102 printf("\nread counts by pid:\n\n");
103
104 printf("%6s %20s %10s %10s %10s\n", "pid", "comm",
105 "# reads", "bytes_req", "bytes_read");
106 printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------",
107 "----------", "----------", "----------");
108
109 foreach my $pid (sort {$reads{$b}{bytes_read} <=>
110 $reads{$a}{bytes_read}} keys %reads) {
111 my $comm = $reads{$pid}{comm};
112 my $total_reads = $reads{$pid}{total_reads};
113 my $bytes_requested = $reads{$pid}{bytes_requested};
114 my $bytes_read = $reads{$pid}{bytes_read};
115
116 printf("%6s %-20s %10s %10s %10s\n", $pid, $comm,
117 $total_reads, $bytes_requested, $bytes_read);
118
119 if (++$count == $nlines) {
120 last;
121 }
122 }
123
124 $count = 0;
125
126 printf("\nwrite counts by pid:\n\n");
127
128 printf("%6s %20s %10s %13s\n", "pid", "comm",
129 "# writes", "bytes_written");
130 printf("%6s %-20s %10s %13s\n", "------", "--------------------",
131 "----------", "-------------");
132
133 foreach my $pid (sort {$writes{$b}{bytes_written} <=>
134 $writes{$a}{bytes_written}} keys %writes) {
135 my $comm = $writes{$pid}{comm};
136 my $total_writes = $writes{$pid}{total_writes};
137 my $bytes_written = $writes{$pid}{bytes_written};
138
139 printf("%6s %-20s %10s %13s\n", $pid, $comm,
140 $total_writes, $bytes_written);
141
142 if (++$count == $nlines) {
143 last;
144 }
145 }
146
147 %reads = ();
148 %writes = ();
149 alarm $interval;
150}
151
152my %unhandled;
153
154sub print_unhandled
155{
156 if ((scalar keys %unhandled) == 0) {
157 return;
158 }
159
160 print "\nunhandled events:\n\n";
161
162 printf("%-40s %10s\n", "event", "count");
163 printf("%-40s %10s\n", "----------------------------------------",
164 "-----------");
165
166 foreach my $event_name (keys %unhandled) {
167 printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
168 }
169}
170
171sub trace_unhandled
172{
173 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
174 $common_pid, $common_comm) = @_;
175
176 $unhandled{$event_name}++;
177}