1aa5d9151SArjan van de Ven#!/usr/bin/perl 2aa5d9151SArjan van de Ven 3aa5d9151SArjan van de Ven# Copyright 2008, Intel Corporation 4aa5d9151SArjan van de Ven# 5aa5d9151SArjan van de Ven# This file is part of the Linux kernel 6aa5d9151SArjan van de Ven# 7aa5d9151SArjan van de Ven# This program file is free software; you can redistribute it and/or modify it 8aa5d9151SArjan van de Ven# under the terms of the GNU General Public License as published by the 9aa5d9151SArjan van de Ven# Free Software Foundation; version 2 of the License. 10aa5d9151SArjan van de Ven# 11aa5d9151SArjan van de Ven# This program is distributed in the hope that it will be useful, but WITHOUT 12aa5d9151SArjan van de Ven# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13aa5d9151SArjan van de Ven# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14aa5d9151SArjan van de Ven# for more details. 15aa5d9151SArjan van de Ven# 16aa5d9151SArjan van de Ven# You should have received a copy of the GNU General Public License 17aa5d9151SArjan van de Ven# along with this program in a file named COPYING; if not, write to the 18aa5d9151SArjan van de Ven# Free Software Foundation, Inc., 19aa5d9151SArjan van de Ven# 51 Franklin Street, Fifth Floor, 20aa5d9151SArjan van de Ven# Boston, MA 02110-1301 USA 21aa5d9151SArjan van de Ven# 22aa5d9151SArjan van de Ven# Authors: 23aa5d9151SArjan van de Ven# Arjan van de Ven <arjan@linux.intel.com> 24aa5d9151SArjan van de Ven 25aa5d9151SArjan van de Ven 26aa5d9151SArjan van de Ven# 27aa5d9151SArjan van de Ven# This script turns a dmesg output into a SVG graphic that shows which 28aa5d9151SArjan van de Ven# functions take how much time. You can view SVG graphics with various 29aa5d9151SArjan van de Ven# programs, including Inkscape, The Gimp and Firefox. 30aa5d9151SArjan van de Ven# 31aa5d9151SArjan van de Ven# 32aa5d9151SArjan van de Ven# For this script to work, the kernel needs to be compiled with the 33aa5d9151SArjan van de Ven# CONFIG_PRINTK_TIME configuration option enabled, and with 34aa5d9151SArjan van de Ven# "initcall_debug" passed on the kernel command line. 35aa5d9151SArjan van de Ven# 36aa5d9151SArjan van de Ven# usage: 37aa5d9151SArjan van de Ven# dmesg | perl scripts/bootgraph.pl > output.svg 38aa5d9151SArjan van de Ven# 39aa5d9151SArjan van de Ven 402a813f8cSAlan Jenkinsuse strict; 412a813f8cSAlan Jenkins 422a813f8cSAlan Jenkinsmy %start; 432a813f8cSAlan Jenkinsmy %end; 44*d3f8ddeaSArjan van de Venmy %type; 45aa5d9151SArjan van de Venmy $done = 0; 46aa5d9151SArjan van de Venmy $maxtime = 0; 4780a398a5SArjan van de Venmy $firsttime = 100; 48aa5d9151SArjan van de Venmy $count = 0; 49ddc7a01aSFrederic Weisbeckermy %pids; 50*d3f8ddeaSArjan van de Venmy %pidctr; 51ddc7a01aSFrederic Weisbecker 52aa5d9151SArjan van de Venwhile (<>) { 53aa5d9151SArjan van de Ven my $line = $_; 545c542368SArnaud Patard if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { 55aa5d9151SArjan van de Ven my $func = $2; 56aa5d9151SArjan van de Ven if ($done == 0) { 57aa5d9151SArjan van de Ven $start{$func} = $1; 58*d3f8ddeaSArjan van de Ven $type{$func} = 0; 5980a398a5SArjan van de Ven if ($1 < $firsttime) { 6080a398a5SArjan van de Ven $firsttime = $1; 6180a398a5SArjan van de Ven } 62aa5d9151SArjan van de Ven } 63aa5d9151SArjan van de Ven if ($line =~ /\@ ([0-9]+)/) { 64ddc7a01aSFrederic Weisbecker $pids{$func} = $1; 65aa5d9151SArjan van de Ven } 66aa5d9151SArjan van de Ven $count = $count + 1; 67aa5d9151SArjan van de Ven } 68aa5d9151SArjan van de Ven 69*d3f8ddeaSArjan van de Ven if ($line =~ /([0-9\.]+)\] async_waiting @ ([0-9]+)/) { 70*d3f8ddeaSArjan van de Ven my $pid = $2; 71*d3f8ddeaSArjan van de Ven my $func; 72*d3f8ddeaSArjan van de Ven if (!defined($pidctr{$pid})) { 73*d3f8ddeaSArjan van de Ven $func = "wait_" . $pid . "_1"; 74*d3f8ddeaSArjan van de Ven $pidctr{$pid} = 1; 75*d3f8ddeaSArjan van de Ven } else { 76*d3f8ddeaSArjan van de Ven $pidctr{$pid} = $pidctr{$pid} + 1; 77*d3f8ddeaSArjan van de Ven $func = "wait_" . $pid . "_" . $pidctr{$pid}; 78*d3f8ddeaSArjan van de Ven } 79*d3f8ddeaSArjan van de Ven if ($done == 0) { 80*d3f8ddeaSArjan van de Ven $start{$func} = $1; 81*d3f8ddeaSArjan van de Ven $type{$func} = 1; 82*d3f8ddeaSArjan van de Ven if ($1 < $firsttime) { 83*d3f8ddeaSArjan van de Ven $firsttime = $1; 84*d3f8ddeaSArjan van de Ven } 85*d3f8ddeaSArjan van de Ven } 86*d3f8ddeaSArjan van de Ven $pids{$func} = $pid; 87*d3f8ddeaSArjan van de Ven $count = $count + 1; 88*d3f8ddeaSArjan van de Ven } 89*d3f8ddeaSArjan van de Ven 905c542368SArnaud Patard if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { 91aa5d9151SArjan van de Ven if ($done == 0) { 92aa5d9151SArjan van de Ven $end{$2} = $1; 93aa5d9151SArjan van de Ven $maxtime = $1; 94aa5d9151SArjan van de Ven } 95aa5d9151SArjan van de Ven } 96*d3f8ddeaSArjan van de Ven 97*d3f8ddeaSArjan van de Ven if ($line =~ /([0-9\.]+)\] async_continuing @ ([0-9]+)/) { 98*d3f8ddeaSArjan van de Ven my $pid = $2; 99*d3f8ddeaSArjan van de Ven my $func = "wait_" . $pid . "_" . $pidctr{$pid}; 100*d3f8ddeaSArjan van de Ven $end{$func} = $1; 101*d3f8ddeaSArjan van de Ven $maxtime = $1; 102*d3f8ddeaSArjan van de Ven } 103aa5d9151SArjan van de Ven if ($line =~ /Write protecting the/) { 104aa5d9151SArjan van de Ven $done = 1; 105aa5d9151SArjan van de Ven } 10680a398a5SArjan van de Ven if ($line =~ /Freeing unused kernel memory/) { 10780a398a5SArjan van de Ven $done = 1; 10880a398a5SArjan van de Ven } 109aa5d9151SArjan van de Ven} 110aa5d9151SArjan van de Ven 111aa5d9151SArjan van de Venif ($count == 0) { 112d1aaf8cfSStephen Hemminger print STDERR <<END; 113d1aaf8cfSStephen HemmingerNo data found in the dmesg. Make sure that 'printk.time=1' and 114d1aaf8cfSStephen Hemminger'initcall_debug' are passed on the kernel command line. 115d1aaf8cfSStephen HemmingerUsage: 116d1aaf8cfSStephen Hemminger dmesg | perl scripts/bootgraph.pl > output.svg 117d1aaf8cfSStephen HemmingerEND 118d1aaf8cfSStephen Hemminger exit 1; 119aa5d9151SArjan van de Ven} 120aa5d9151SArjan van de Ven 121aa5d9151SArjan van de Venprint "<?xml version=\"1.0\" standalone=\"no\"?> \n"; 12240c8c85aSArjan van de Venprint "<svg width=\"2000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"; 123aa5d9151SArjan van de Ven 124aa5d9151SArjan van de Venmy @styles; 125aa5d9151SArjan van de Ven 126aa5d9151SArjan van de Ven$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 127aa5d9151SArjan van de Ven$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 128aa5d9151SArjan van de Ven$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 129aa5d9151SArjan van de Ven$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 130aa5d9151SArjan van de Ven$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 131aa5d9151SArjan van de Ven$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 132aa5d9151SArjan van de Ven$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 133aa5d9151SArjan van de Ven$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 134aa5d9151SArjan van de Ven$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 135aa5d9151SArjan van de Ven$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 136aa5d9151SArjan van de Ven$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 137aa5d9151SArjan van de Ven$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 138aa5d9151SArjan van de Ven 139*d3f8ddeaSArjan van de Venmy $style_wait = "fill:rgb(128,128,128);fill-opacity:0.5;stroke-width:0;stroke:rgb(0,0,0)"; 140*d3f8ddeaSArjan van de Ven 14140c8c85aSArjan van de Venmy $mult = 1950.0 / ($maxtime - $firsttime); 14240c8c85aSArjan van de Venmy $threshold2 = ($maxtime - $firsttime) / 120.0; 14340c8c85aSArjan van de Venmy $threshold = $threshold2/10; 144aa5d9151SArjan van de Venmy $stylecounter = 0; 145ddc7a01aSFrederic Weisbeckermy %rows; 146ddc7a01aSFrederic Weisbeckermy $rowscount = 1; 14706d1cd26SAlan Jenkinsmy @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start); 14868f96c0cSStephen Hemminger 14968f96c0cSStephen Hemmingerforeach my $key (@initcalls) { 150aa5d9151SArjan van de Ven my $duration = $end{$key} - $start{$key}; 151aa5d9151SArjan van de Ven 152aa5d9151SArjan van de Ven if ($duration >= $threshold) { 15340c8c85aSArjan van de Ven my ($s, $s2, $s3, $e, $w, $y, $y2, $style); 1542a813f8cSAlan Jenkins my $pid = $pids{$key}; 15507d18904SFrederic Weisbecker 15607d18904SFrederic Weisbecker if (!defined($rows{$pid})) { 15707d18904SFrederic Weisbecker $rows{$pid} = $rowscount; 15807d18904SFrederic Weisbecker $rowscount = $rowscount + 1; 15907d18904SFrederic Weisbecker } 16006d1cd26SAlan Jenkins $s = ($start{$key} - $firsttime) * $mult; 161aa5d9151SArjan van de Ven $s2 = $s + 6; 16240c8c85aSArjan van de Ven $s3 = $s + 1; 16380a398a5SArjan van de Ven $e = ($end{$key} - $firsttime) * $mult; 164aa5d9151SArjan van de Ven $w = $e - $s; 165aa5d9151SArjan van de Ven 166ddc7a01aSFrederic Weisbecker $y = $rows{$pid} * 150; 167aa5d9151SArjan van de Ven $y2 = $y + 4; 168aa5d9151SArjan van de Ven 169aa5d9151SArjan van de Ven $style = $styles[$stylecounter]; 170aa5d9151SArjan van de Ven $stylecounter = $stylecounter + 1; 171aa5d9151SArjan van de Ven if ($stylecounter > 11) { 172aa5d9151SArjan van de Ven $stylecounter = 0; 173aa5d9151SArjan van de Ven }; 174aa5d9151SArjan van de Ven 175*d3f8ddeaSArjan van de Ven if ($type{$key} == 1) { 176*d3f8ddeaSArjan van de Ven $y = $y + 15; 177*d3f8ddeaSArjan van de Ven print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"115\" style=\"$style_wait\"/>\n"; 178*d3f8ddeaSArjan van de Ven } else { 179aa5d9151SArjan van de Ven print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n"; 18040c8c85aSArjan van de Ven if ($duration >= $threshold2) { 181aa5d9151SArjan van de Ven print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n"; 18240c8c85aSArjan van de Ven } else { 18340c8c85aSArjan van de Ven print "<text transform=\"translate($s3,$y2) rotate(90)\" font-size=\"3pt\">$key</text>\n"; 18440c8c85aSArjan van de Ven } 185aa5d9151SArjan van de Ven } 186aa5d9151SArjan van de Ven } 187*d3f8ddeaSArjan van de Ven} 188aa5d9151SArjan van de Ven 189aa5d9151SArjan van de Ven 190aa5d9151SArjan van de Ven# print the time line on top 19180a398a5SArjan van de Venmy $time = $firsttime; 19280a398a5SArjan van de Venmy $step = ($maxtime - $firsttime) / 15; 193aa5d9151SArjan van de Venwhile ($time < $maxtime) { 1942a813f8cSAlan Jenkins my $s3 = ($time - $firsttime) * $mult; 19580a398a5SArjan van de Ven my $tm = int($time * 100) / 100.0; 1962a813f8cSAlan Jenkins print "<text transform=\"translate($s3,89) rotate(90)\">$tm</text>\n"; 19780a398a5SArjan van de Ven $time = $time + $step; 198aa5d9151SArjan van de Ven} 199aa5d9151SArjan van de Ven 200aa5d9151SArjan van de Venprint "</svg>\n"; 201