1 #!/usr/bin/perl -w 2 # (c) 2009, Tom Zanussi <tzanussi (at] gmail.com> 3 # Licensed under the terms of the GNU GPL License version 2 4 5 # Displays workqueue stats 6 # 7 # Usage: 8 # 9 # perf record -c 1 -f -a -R -e workqueue:workqueue_creation -e 10 # workqueue:workqueue_destruction -e workqueue:workqueue_execution 11 # -e workqueue:workqueue_insertion 12 # 13 # perf script -p -s tools/perf/scripts/perl/workqueue-stats.pl 14 15 use 5.010000; 16 use strict; 17 use warnings; 18 19 use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; 20 use lib "./Perf-Trace-Util/lib"; 21 use Perf::Trace::Core; 22 use Perf::Trace::Util; 23 24 my @cpus; 25 26 sub workqueue::workqueue_destruction 27 { 28 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 29 $common_pid, $common_comm, 30 $thread_comm, $thread_pid) = @_; 31 32 $cpus[$common_cpu]{$thread_pid}{destroyed}++; 33 $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm; 34 } 35 36 sub workqueue::workqueue_creation 37 { 38 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 39 $common_pid, $common_comm, 40 $thread_comm, $thread_pid, $cpu) = @_; 41 42 $cpus[$common_cpu]{$thread_pid}{created}++; 43 $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm; 44 } 45 46 sub workqueue::workqueue_execution 47 { 48 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 49 $common_pid, $common_comm, 50 $thread_comm, $thread_pid, $func) = @_; 51 52 $cpus[$common_cpu]{$thread_pid}{executed}++; 53 $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm; 54 } 55 56 sub workqueue::workqueue_insertion 57 { 58 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 59 $common_pid, $common_comm, 60 $thread_comm, $thread_pid, $func) = @_; 61 62 $cpus[$common_cpu]{$thread_pid}{inserted}++; 63 $cpus[$common_cpu]{$thread_pid}{comm} = $thread_comm; 64 } 65 66 sub trace_end 67 { 68 print "workqueue work stats:\n\n"; 69 my $cpu = 0; 70 printf("%3s %6s %6s\t%-20s\n", "cpu", "ins", "exec", "name"); 71 printf("%3s %6s %6s\t%-20s\n", "---", "---", "----", "----"); 72 foreach my $pidhash (@cpus) { 73 while ((my $pid, my $wqhash) = each %$pidhash) { 74 my $ins = $$wqhash{'inserted'} || 0; 75 my $exe = $$wqhash{'executed'} || 0; 76 my $comm = $$wqhash{'comm'} || ""; 77 if ($ins || $exe) { 78 printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm); 79 } 80 } 81 $cpu++; 82 } 83 84 $cpu = 0; 85 print "\nworkqueue lifecycle stats:\n\n"; 86 printf("%3s %6s %6s\t%-20s\n", "cpu", "created", "destroyed", "name"); 87 printf("%3s %6s %6s\t%-20s\n", "---", "-------", "---------", "----"); 88 foreach my $pidhash (@cpus) { 89 while ((my $pid, my $wqhash) = each %$pidhash) { 90 my $created = $$wqhash{'created'} || 0; 91 my $destroyed = $$wqhash{'destroyed'} || 0; 92 my $comm = $$wqhash{'comm'} || ""; 93 if ($created || $destroyed) { 94 printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed, 95 $comm); 96 } 97 } 98 $cpu++; 99 } 100 101 print_unhandled(); 102 } 103 104 my %unhandled; 105 106 sub print_unhandled 107 { 108 if ((scalar keys %unhandled) == 0) { 109 return; 110 } 111 112 print "\nunhandled events:\n\n"; 113 114 printf("%-40s %10s\n", "event", "count"); 115 printf("%-40s %10s\n", "----------------------------------------", 116 "-----------"); 117 118 foreach my $event_name (keys %unhandled) { 119 printf("%-40s %10d\n", $event_name, $unhandled{$event_name}); 120 } 121 } 122 123 sub trace_unhandled 124 { 125 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, 126 $common_pid, $common_comm) = @_; 127 128 $unhandled{$event_name}++; 129 } 130