xref: /OK3568_Linux_fs/kernel/tools/perf/scripts/perl/wakeup-latency.pl (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/perl -w
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun# Display avg/min/max wakeup latency
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun# The common_* event handler fields are the most useful fields common to
8*4882a593Smuzhiyun# all events.  They don't necessarily correspond to the 'common_*' fields
9*4882a593Smuzhiyun# in the status files.  Those fields not available as handler params can
10*4882a593Smuzhiyun# be retrieved via script functions of the form get_common_*().
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*4882a593Smuzhiyun
21*4882a593Smuzhiyunmy %last_wakeup;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyunmy $max_wakeup_latency;
24*4882a593Smuzhiyunmy $min_wakeup_latency;
25*4882a593Smuzhiyunmy $total_wakeup_latency = 0;
26*4882a593Smuzhiyunmy $total_wakeups = 0;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyunsub sched::sched_switch
29*4882a593Smuzhiyun{
30*4882a593Smuzhiyun    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
31*4882a593Smuzhiyun	$common_pid, $common_comm, $common_callchain,
32*4882a593Smuzhiyun	$prev_comm, $prev_pid, $prev_prio, $prev_state, $next_comm, $next_pid,
33*4882a593Smuzhiyun	$next_prio) = @_;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun    my $wakeup_ts = $last_wakeup{$common_cpu}{ts};
36*4882a593Smuzhiyun    if ($wakeup_ts) {
37*4882a593Smuzhiyun	my $switch_ts = nsecs($common_secs, $common_nsecs);
38*4882a593Smuzhiyun	my $wakeup_latency = $switch_ts - $wakeup_ts;
39*4882a593Smuzhiyun	if ($wakeup_latency > $max_wakeup_latency) {
40*4882a593Smuzhiyun	    $max_wakeup_latency = $wakeup_latency;
41*4882a593Smuzhiyun	}
42*4882a593Smuzhiyun	if ($wakeup_latency < $min_wakeup_latency) {
43*4882a593Smuzhiyun	    $min_wakeup_latency = $wakeup_latency;
44*4882a593Smuzhiyun	}
45*4882a593Smuzhiyun	$total_wakeup_latency += $wakeup_latency;
46*4882a593Smuzhiyun	$total_wakeups++;
47*4882a593Smuzhiyun    }
48*4882a593Smuzhiyun    $last_wakeup{$common_cpu}{ts} = 0;
49*4882a593Smuzhiyun}
50*4882a593Smuzhiyun
51*4882a593Smuzhiyunsub sched::sched_wakeup
52*4882a593Smuzhiyun{
53*4882a593Smuzhiyun    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
54*4882a593Smuzhiyun	$common_pid, $common_comm, $common_callchain,
55*4882a593Smuzhiyun	$comm, $pid, $prio, $success, $target_cpu) = @_;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun    $last_wakeup{$target_cpu}{ts} = nsecs($common_secs, $common_nsecs);
58*4882a593Smuzhiyun}
59*4882a593Smuzhiyun
60*4882a593Smuzhiyunsub trace_begin
61*4882a593Smuzhiyun{
62*4882a593Smuzhiyun    $min_wakeup_latency = 1000000000;
63*4882a593Smuzhiyun    $max_wakeup_latency = 0;
64*4882a593Smuzhiyun}
65*4882a593Smuzhiyun
66*4882a593Smuzhiyunsub trace_end
67*4882a593Smuzhiyun{
68*4882a593Smuzhiyun    printf("wakeup_latency stats:\n\n");
69*4882a593Smuzhiyun    print "total_wakeups: $total_wakeups\n";
70*4882a593Smuzhiyun    if ($total_wakeups) {
71*4882a593Smuzhiyun	printf("avg_wakeup_latency (ns): %u\n",
72*4882a593Smuzhiyun	       avg($total_wakeup_latency, $total_wakeups));
73*4882a593Smuzhiyun    } else {
74*4882a593Smuzhiyun	printf("avg_wakeup_latency (ns): N/A\n");
75*4882a593Smuzhiyun    }
76*4882a593Smuzhiyun    printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
77*4882a593Smuzhiyun    printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun    print_unhandled();
80*4882a593Smuzhiyun}
81*4882a593Smuzhiyun
82*4882a593Smuzhiyunmy %unhandled;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyunsub print_unhandled
85*4882a593Smuzhiyun{
86*4882a593Smuzhiyun    if ((scalar keys %unhandled) == 0) {
87*4882a593Smuzhiyun	return;
88*4882a593Smuzhiyun    }
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun    print "\nunhandled events:\n\n";
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun    printf("%-40s  %10s\n", "event", "count");
93*4882a593Smuzhiyun    printf("%-40s  %10s\n", "----------------------------------------",
94*4882a593Smuzhiyun	   "-----------");
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun    foreach my $event_name (keys %unhandled) {
97*4882a593Smuzhiyun	printf("%-40s  %10d\n", $event_name, $unhandled{$event_name});
98*4882a593Smuzhiyun    }
99*4882a593Smuzhiyun}
100*4882a593Smuzhiyun
101*4882a593Smuzhiyunsub trace_unhandled
102*4882a593Smuzhiyun{
103*4882a593Smuzhiyun    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
104*4882a593Smuzhiyun	$common_pid, $common_comm, $common_callchain) = @_;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun    $unhandled{$event_name}++;
107*4882a593Smuzhiyun}
108