162306a36Sopenharmony_ci#!/usr/bin/perl -w 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only 362306a36Sopenharmony_ci# (c) 2010, Tom Zanussi <tzanussi@gmail.com> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci# read/write top 662306a36Sopenharmony_ci# 762306a36Sopenharmony_ci# Periodically displays system-wide r/w call activity, broken down by 862306a36Sopenharmony_ci# pid. If an [interval] arg is specified, the display will be 962306a36Sopenharmony_ci# refreshed every [interval] seconds. The default interval is 3 1062306a36Sopenharmony_ci# seconds. 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciuse 5.010000; 1362306a36Sopenharmony_ciuse strict; 1462306a36Sopenharmony_ciuse warnings; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciuse lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; 1762306a36Sopenharmony_ciuse lib "./Perf-Trace-Util/lib"; 1862306a36Sopenharmony_ciuse Perf::Trace::Core; 1962306a36Sopenharmony_ciuse Perf::Trace::Util; 2062306a36Sopenharmony_ciuse POSIX qw/SIGALRM SA_RESTART/; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cimy $default_interval = 3; 2362306a36Sopenharmony_cimy $nlines = 20; 2462306a36Sopenharmony_cimy $print_thread; 2562306a36Sopenharmony_cimy $print_pending = 0; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cimy %reads; 2862306a36Sopenharmony_cimy %writes; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cimy $interval = shift; 3162306a36Sopenharmony_ciif (!$interval) { 3262306a36Sopenharmony_ci $interval = $default_interval; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cisub syscalls::sys_exit_read 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 3862306a36Sopenharmony_ci $common_pid, $common_comm, $common_callchain, 3962306a36Sopenharmony_ci $nr, $ret) = @_; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci print_check(); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci if ($ret > 0) { 4462306a36Sopenharmony_ci $reads{$common_pid}{bytes_read} += $ret; 4562306a36Sopenharmony_ci } else { 4662306a36Sopenharmony_ci if (!defined ($reads{$common_pid}{bytes_read})) { 4762306a36Sopenharmony_ci $reads{$common_pid}{bytes_read} = 0; 4862306a36Sopenharmony_ci } 4962306a36Sopenharmony_ci $reads{$common_pid}{errors}{$ret}++; 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cisub syscalls::sys_enter_read 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 5662306a36Sopenharmony_ci $common_pid, $common_comm, $common_callchain, 5762306a36Sopenharmony_ci $nr, $fd, $buf, $count) = @_; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci print_check(); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci $reads{$common_pid}{bytes_requested} += $count; 6262306a36Sopenharmony_ci $reads{$common_pid}{total_reads}++; 6362306a36Sopenharmony_ci $reads{$common_pid}{comm} = $common_comm; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cisub syscalls::sys_exit_write 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 6962306a36Sopenharmony_ci $common_pid, $common_comm, $common_callchain, 7062306a36Sopenharmony_ci $nr, $ret) = @_; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci print_check(); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if ($ret <= 0) { 7562306a36Sopenharmony_ci $writes{$common_pid}{errors}{$ret}++; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cisub syscalls::sys_enter_write 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 8262306a36Sopenharmony_ci $common_pid, $common_comm, $common_callchain, 8362306a36Sopenharmony_ci $nr, $fd, $buf, $count) = @_; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci print_check(); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci $writes{$common_pid}{bytes_written} += $count; 8862306a36Sopenharmony_ci $writes{$common_pid}{total_writes}++; 8962306a36Sopenharmony_ci $writes{$common_pid}{comm} = $common_comm; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cisub trace_begin 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci my $sa = POSIX::SigAction->new(\&set_print_pending); 9562306a36Sopenharmony_ci $sa->flags(SA_RESTART); 9662306a36Sopenharmony_ci $sa->safe(1); 9762306a36Sopenharmony_ci POSIX::sigaction(SIGALRM, $sa) or die "Can't set SIGALRM handler: $!\n"; 9862306a36Sopenharmony_ci alarm 1; 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cisub trace_end 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci print_unhandled(); 10462306a36Sopenharmony_ci print_totals(); 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cisub print_check() 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci if ($print_pending == 1) { 11062306a36Sopenharmony_ci $print_pending = 0; 11162306a36Sopenharmony_ci print_totals(); 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cisub set_print_pending() 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci $print_pending = 1; 11862306a36Sopenharmony_ci alarm $interval; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cisub print_totals 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci my $count; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci $count = 0; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci clear_term(); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci printf("\nread counts by pid:\n\n"); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci printf("%6s %20s %10s %10s %10s\n", "pid", "comm", 13262306a36Sopenharmony_ci "# reads", "bytes_req", "bytes_read"); 13362306a36Sopenharmony_ci printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------", 13462306a36Sopenharmony_ci "----------", "----------", "----------"); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=> 13762306a36Sopenharmony_ci ($reads{$a}{bytes_read} || 0) } keys %reads) { 13862306a36Sopenharmony_ci my $comm = $reads{$pid}{comm} || ""; 13962306a36Sopenharmony_ci my $total_reads = $reads{$pid}{total_reads} || 0; 14062306a36Sopenharmony_ci my $bytes_requested = $reads{$pid}{bytes_requested} || 0; 14162306a36Sopenharmony_ci my $bytes_read = $reads{$pid}{bytes_read} || 0; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci printf("%6s %-20s %10s %10s %10s\n", $pid, $comm, 14462306a36Sopenharmony_ci $total_reads, $bytes_requested, $bytes_read); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (++$count == $nlines) { 14762306a36Sopenharmony_ci last; 14862306a36Sopenharmony_ci } 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci $count = 0; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci printf("\nwrite counts by pid:\n\n"); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci printf("%6s %20s %10s %13s\n", "pid", "comm", 15662306a36Sopenharmony_ci "# writes", "bytes_written"); 15762306a36Sopenharmony_ci printf("%6s %-20s %10s %13s\n", "------", "--------------------", 15862306a36Sopenharmony_ci "----------", "-------------"); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=> 16162306a36Sopenharmony_ci ($writes{$a}{bytes_written} || 0)} keys %writes) { 16262306a36Sopenharmony_ci my $comm = $writes{$pid}{comm} || ""; 16362306a36Sopenharmony_ci my $total_writes = $writes{$pid}{total_writes} || 0; 16462306a36Sopenharmony_ci my $bytes_written = $writes{$pid}{bytes_written} || 0; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci printf("%6s %-20s %10s %13s\n", $pid, $comm, 16762306a36Sopenharmony_ci $total_writes, $bytes_written); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci if (++$count == $nlines) { 17062306a36Sopenharmony_ci last; 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci %reads = (); 17562306a36Sopenharmony_ci %writes = (); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cimy %unhandled; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cisub print_unhandled 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci if ((scalar keys %unhandled) == 0) { 18362306a36Sopenharmony_ci return; 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci print "\nunhandled events:\n\n"; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci printf("%-40s %10s\n", "event", "count"); 18962306a36Sopenharmony_ci printf("%-40s %10s\n", "----------------------------------------", 19062306a36Sopenharmony_ci "-----------"); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci foreach my $event_name (keys %unhandled) { 19362306a36Sopenharmony_ci printf("%-40s %10d\n", $event_name, $unhandled{$event_name}); 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cisub trace_unhandled 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 20062306a36Sopenharmony_ci $common_pid, $common_comm, $common_callchain) = @_; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci $unhandled{$event_name}++; 20362306a36Sopenharmony_ci} 204