Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/scripts/bootgraph.pl
10818 views
1
#!/usr/bin/perl
2
3
# Copyright 2008, Intel Corporation
4
#
5
# This file is part of the Linux kernel
6
#
7
# This program file is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by the
9
# Free Software Foundation; version 2 of the License.
10
#
11
# This program is distributed in the hope that it will be useful, but WITHOUT
12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
# for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program in a file named COPYING; if not, write to the
18
# Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor,
20
# Boston, MA 02110-1301 USA
21
#
22
# Authors:
23
# Arjan van de Ven <[email protected]>
24
25
26
#
27
# This script turns a dmesg output into a SVG graphic that shows which
28
# functions take how much time. You can view SVG graphics with various
29
# programs, including Inkscape, The Gimp and Firefox.
30
#
31
#
32
# For this script to work, the kernel needs to be compiled with the
33
# CONFIG_PRINTK_TIME configuration option enabled, and with
34
# "initcall_debug" passed on the kernel command line.
35
#
36
# usage:
37
# dmesg | perl scripts/bootgraph.pl > output.svg
38
#
39
40
use strict;
41
42
my %start;
43
my %end;
44
my %type;
45
my $done = 0;
46
my $maxtime = 0;
47
my $firsttime = 100;
48
my $count = 0;
49
my %pids;
50
my %pidctr;
51
52
while (<>) {
53
my $line = $_;
54
if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_\.]+)\+/) {
55
my $func = $2;
56
if ($done == 0) {
57
$start{$func} = $1;
58
$type{$func} = 0;
59
if ($1 < $firsttime) {
60
$firsttime = $1;
61
}
62
}
63
if ($line =~ /\@ ([0-9]+)/) {
64
$pids{$func} = $1;
65
}
66
$count = $count + 1;
67
}
68
69
if ($line =~ /([0-9\.]+)\] async_waiting @ ([0-9]+)/) {
70
my $pid = $2;
71
my $func;
72
if (!defined($pidctr{$pid})) {
73
$func = "wait_" . $pid . "_1";
74
$pidctr{$pid} = 1;
75
} else {
76
$pidctr{$pid} = $pidctr{$pid} + 1;
77
$func = "wait_" . $pid . "_" . $pidctr{$pid};
78
}
79
if ($done == 0) {
80
$start{$func} = $1;
81
$type{$func} = 1;
82
if ($1 < $firsttime) {
83
$firsttime = $1;
84
}
85
}
86
$pids{$func} = $pid;
87
$count = $count + 1;
88
}
89
90
if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_\.]+)\+.*returned/) {
91
if ($done == 0) {
92
$end{$2} = $1;
93
$maxtime = $1;
94
}
95
}
96
97
if ($line =~ /([0-9\.]+)\] async_continuing @ ([0-9]+)/) {
98
my $pid = $2;
99
my $func = "wait_" . $pid . "_" . $pidctr{$pid};
100
$end{$func} = $1;
101
$maxtime = $1;
102
}
103
if ($line =~ /Write protecting the/) {
104
$done = 1;
105
}
106
if ($line =~ /Freeing unused kernel memory/) {
107
$done = 1;
108
}
109
}
110
111
if ($count == 0) {
112
print STDERR <<END;
113
No data found in the dmesg. Make sure that 'printk.time=1' and
114
'initcall_debug' are passed on the kernel command line.
115
Usage:
116
dmesg | perl scripts/bootgraph.pl > output.svg
117
END
118
exit 1;
119
}
120
121
print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
122
print "<svg width=\"2000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
123
124
my @styles;
125
126
$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
127
$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
128
$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
129
$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
130
$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
131
$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
132
$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
133
$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
134
$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
135
$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
136
$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
137
$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
138
139
my $style_wait = "fill:rgb(128,128,128);fill-opacity:0.5;stroke-width:0;stroke:rgb(0,0,0)";
140
141
my $mult = 1950.0 / ($maxtime - $firsttime);
142
my $threshold2 = ($maxtime - $firsttime) / 120.0;
143
my $threshold = $threshold2/10;
144
my $stylecounter = 0;
145
my %rows;
146
my $rowscount = 1;
147
my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start);
148
149
foreach my $key (@initcalls) {
150
my $duration = $end{$key} - $start{$key};
151
152
if ($duration >= $threshold) {
153
my ($s, $s2, $s3, $e, $w, $y, $y2, $style);
154
my $pid = $pids{$key};
155
156
if (!defined($rows{$pid})) {
157
$rows{$pid} = $rowscount;
158
$rowscount = $rowscount + 1;
159
}
160
$s = ($start{$key} - $firsttime) * $mult;
161
$s2 = $s + 6;
162
$s3 = $s + 1;
163
$e = ($end{$key} - $firsttime) * $mult;
164
$w = $e - $s;
165
166
$y = $rows{$pid} * 150;
167
$y2 = $y + 4;
168
169
$style = $styles[$stylecounter];
170
$stylecounter = $stylecounter + 1;
171
if ($stylecounter > 11) {
172
$stylecounter = 0;
173
};
174
175
if ($type{$key} == 1) {
176
$y = $y + 15;
177
print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"115\" style=\"$style_wait\"/>\n";
178
} else {
179
print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
180
if ($duration >= $threshold2) {
181
print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
182
} else {
183
print "<text transform=\"translate($s3,$y2) rotate(90)\" font-size=\"3pt\">$key</text>\n";
184
}
185
}
186
}
187
}
188
189
190
# print the time line on top
191
my $time = $firsttime;
192
my $step = ($maxtime - $firsttime) / 15;
193
while ($time < $maxtime) {
194
my $s3 = ($time - $firsttime) * $mult;
195
my $tm = int($time * 100) / 100.0;
196
print "<text transform=\"translate($s3,89) rotate(90)\">$tm</text>\n";
197
$time = $time + $step;
198
}
199
200
print "</svg>\n";
201
202