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