diff options
| -rw-r--r-- | tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm | 6 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/rwtop-record | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/rwtop-report | 23 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/rwtop.pl | 177 | ||||
| -rw-r--r-- | tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py | 3 | ||||
| -rw-r--r-- | tools/perf/scripts/python/bin/sctop-record | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/python/bin/sctop-report | 24 | ||||
| -rw-r--r-- | tools/perf/scripts/python/sctop.py | 78 |
8 files changed, 315 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 | ||
| 16 | our @EXPORT = qw( | 16 | our @EXPORT = qw( |
| 17 | avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs | 17 | avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs |
| 18 | clear_term | ||
| 18 | ); | 19 | ); |
| 19 | 20 | ||
| 20 | our $VERSION = '0.01'; | 21 | our $VERSION = '0.01'; |
| @@ -55,6 +56,11 @@ sub nsecs_str { | |||
| 55 | return $str; | 56 | return $str; |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 59 | sub clear_term | ||
| 60 | { | ||
| 61 | print "\x1b[H\x1b[2J"; | ||
| 62 | } | ||
| 63 | |||
| 58 | 1; | 64 | 1; |
| 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 | ||
| 2 | perf 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] | ||
| 4 | n_args=0 | ||
| 5 | for i in "$@" | ||
| 6 | do | ||
| 7 | if expr match "$i" "-" > /dev/null ; then | ||
| 8 | break | ||
| 9 | fi | ||
| 10 | n_args=$(( $n_args + 1 )) | ||
| 11 | done | ||
| 12 | if [ "$n_args" -gt 1 ] ; then | ||
| 13 | echo "usage: rwtop-report [interval]" | ||
| 14 | exit | ||
| 15 | fi | ||
| 16 | if [ "$n_args" -gt 0 ] ; then | ||
| 17 | interval=$1 | ||
| 18 | shift | ||
| 19 | fi | ||
| 20 | perf 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 | |||
| 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 | |||
| 25 | my %reads; | ||
| 26 | my %writes; | ||
| 27 | |||
| 28 | my $interval = shift; | ||
| 29 | if (!$interval) { | ||
| 30 | $interval = $default_interval; | ||
| 31 | } | ||
| 32 | |||
| 33 | sub 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 | |||
| 49 | sub 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 | |||
| 60 | sub 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 | |||
| 71 | sub 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 | |||
| 82 | sub trace_begin | ||
| 83 | { | ||
| 84 | $SIG{ALRM} = \&print_totals; | ||
| 85 | alarm 1; | ||
| 86 | } | ||
| 87 | |||
| 88 | sub trace_end | ||
| 89 | { | ||
| 90 | print_unhandled(); | ||
| 91 | print_totals(); | ||
| 92 | } | ||
| 93 | |||
| 94 | sub 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 | |||
| 152 | my %unhandled; | ||
| 153 | |||
| 154 | sub 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 | |||
| 171 | sub 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 | } | ||
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py index 83e91435ed09..9689bc0acd9f 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py | |||
| @@ -23,3 +23,6 @@ def nsecs_nsecs(nsecs): | |||
| 23 | def nsecs_str(nsecs): | 23 | def nsecs_str(nsecs): |
| 24 | str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)), | 24 | str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)), |
| 25 | return str | 25 | return str |
| 26 | |||
| 27 | def clear_term(): | ||
| 28 | print("\x1b[H\x1b[2J") | ||
diff --git a/tools/perf/scripts/python/bin/sctop-record b/tools/perf/scripts/python/bin/sctop-record new file mode 100644 index 000000000000..27ccffa26ab4 --- /dev/null +++ b/tools/perf/scripts/python/bin/sctop-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter $@ | ||
diff --git a/tools/perf/scripts/python/bin/sctop-report b/tools/perf/scripts/python/bin/sctop-report new file mode 100644 index 000000000000..b01c842ae7b4 --- /dev/null +++ b/tools/perf/scripts/python/bin/sctop-report | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: syscall top | ||
| 3 | # args: [comm] [interval] | ||
| 4 | n_args=0 | ||
| 5 | for i in "$@" | ||
| 6 | do | ||
| 7 | if expr match "$i" "-" > /dev/null ; then | ||
| 8 | break | ||
| 9 | fi | ||
| 10 | n_args=$(( $n_args + 1 )) | ||
| 11 | done | ||
| 12 | if [ "$n_args" -gt 2 ] ; then | ||
| 13 | echo "usage: sctop-report [comm] [interval]" | ||
| 14 | exit | ||
| 15 | fi | ||
| 16 | if [ "$n_args" -gt 1 ] ; then | ||
| 17 | comm=$1 | ||
| 18 | interval=$2 | ||
| 19 | shift 2 | ||
| 20 | elif [ "$n_args" -gt 0 ] ; then | ||
| 21 | interval=$1 | ||
| 22 | shift | ||
| 23 | fi | ||
| 24 | perf trace $@ -s ~/libexec/perf-core/scripts/python/sctop.py $comm $interval | ||
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py new file mode 100644 index 000000000000..6cafad40c296 --- /dev/null +++ b/tools/perf/scripts/python/sctop.py | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | # system call top | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Periodically displays system-wide system call totals, broken down by | ||
| 6 | # syscall. If a [comm] arg is specified, only syscalls called by | ||
| 7 | # [comm] are displayed. If an [interval] arg is specified, the display | ||
| 8 | # will be refreshed every [interval] seconds. The default interval is | ||
| 9 | # 3 seconds. | ||
| 10 | |||
| 11 | import thread | ||
| 12 | import time | ||
| 13 | import os | ||
| 14 | import sys | ||
| 15 | |||
| 16 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 17 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 18 | |||
| 19 | from perf_trace_context import * | ||
| 20 | from Core import * | ||
| 21 | from Util import * | ||
| 22 | |||
| 23 | usage = "perf trace -s syscall-counts.py [comm] [interval]\n"; | ||
| 24 | |||
| 25 | for_comm = None | ||
| 26 | default_interval = 3 | ||
| 27 | interval = default_interval | ||
| 28 | |||
| 29 | if len(sys.argv) > 3: | ||
| 30 | sys.exit(usage) | ||
| 31 | |||
| 32 | if len(sys.argv) > 2: | ||
| 33 | for_comm = sys.argv[1] | ||
| 34 | interval = int(sys.argv[2]) | ||
| 35 | elif len(sys.argv) > 1: | ||
| 36 | try: | ||
| 37 | interval = int(sys.argv[1]) | ||
| 38 | except ValueError: | ||
| 39 | for_comm = sys.argv[1] | ||
| 40 | interval = default_interval | ||
| 41 | |||
| 42 | syscalls = autodict() | ||
| 43 | |||
| 44 | def trace_begin(): | ||
| 45 | thread.start_new_thread(print_syscall_totals, (interval,)) | ||
| 46 | pass | ||
| 47 | |||
| 48 | def raw_syscalls__sys_enter(event_name, context, common_cpu, | ||
| 49 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 50 | id, args): | ||
| 51 | if for_comm is not None: | ||
| 52 | if common_comm != for_comm: | ||
| 53 | return | ||
| 54 | try: | ||
| 55 | syscalls[id] += 1 | ||
| 56 | except TypeError: | ||
| 57 | syscalls[id] = 1 | ||
| 58 | |||
| 59 | def print_syscall_totals(interval): | ||
| 60 | while 1: | ||
| 61 | clear_term() | ||
| 62 | if for_comm is not None: | ||
| 63 | print "\nsyscall events for %s:\n\n" % (for_comm), | ||
| 64 | else: | ||
| 65 | print "\nsyscall events:\n\n", | ||
| 66 | |||
| 67 | print "%-40s %10s\n" % ("event", "count"), | ||
| 68 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 69 | "----------"), | ||
| 70 | |||
| 71 | for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ | ||
| 72 | reverse = True): | ||
| 73 | try: | ||
| 74 | print "%-40d %10d\n" % (id, val), | ||
| 75 | except TypeError: | ||
| 76 | pass | ||
| 77 | syscalls.clear() | ||
| 78 | time.sleep(interval) | ||
