1*aa5d9151SArjan van de Ven#!/usr/bin/perl 2*aa5d9151SArjan van de Ven 3*aa5d9151SArjan van de Ven# Copyright 2008, Intel Corporation 4*aa5d9151SArjan van de Ven# 5*aa5d9151SArjan van de Ven# This file is part of the Linux kernel 6*aa5d9151SArjan van de Ven# 7*aa5d9151SArjan van de Ven# This program file is free software; you can redistribute it and/or modify it 8*aa5d9151SArjan van de Ven# under the terms of the GNU General Public License as published by the 9*aa5d9151SArjan van de Ven# Free Software Foundation; version 2 of the License. 10*aa5d9151SArjan van de Ven# 11*aa5d9151SArjan van de Ven# This program is distributed in the hope that it will be useful, but WITHOUT 12*aa5d9151SArjan van de Ven# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*aa5d9151SArjan van de Ven# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*aa5d9151SArjan van de Ven# for more details. 15*aa5d9151SArjan van de Ven# 16*aa5d9151SArjan van de Ven# You should have received a copy of the GNU General Public License 17*aa5d9151SArjan van de Ven# along with this program in a file named COPYING; if not, write to the 18*aa5d9151SArjan van de Ven# Free Software Foundation, Inc., 19*aa5d9151SArjan van de Ven# 51 Franklin Street, Fifth Floor, 20*aa5d9151SArjan van de Ven# Boston, MA 02110-1301 USA 21*aa5d9151SArjan van de Ven# 22*aa5d9151SArjan van de Ven# Authors: 23*aa5d9151SArjan van de Ven# Arjan van de Ven <arjan@linux.intel.com> 24*aa5d9151SArjan van de Ven 25*aa5d9151SArjan van de Ven 26*aa5d9151SArjan van de Ven# 27*aa5d9151SArjan van de Ven# This script turns a dmesg output into a SVG graphic that shows which 28*aa5d9151SArjan van de Ven# functions take how much time. You can view SVG graphics with various 29*aa5d9151SArjan van de Ven# programs, including Inkscape, The Gimp and Firefox. 30*aa5d9151SArjan van de Ven# 31*aa5d9151SArjan van de Ven# 32*aa5d9151SArjan van de Ven# For this script to work, the kernel needs to be compiled with the 33*aa5d9151SArjan van de Ven# CONFIG_PRINTK_TIME configuration option enabled, and with 34*aa5d9151SArjan van de Ven# "initcall_debug" passed on the kernel command line. 35*aa5d9151SArjan van de Ven# 36*aa5d9151SArjan van de Ven# usage: 37*aa5d9151SArjan van de Ven# dmesg | perl scripts/bootgraph.pl > output.svg 38*aa5d9151SArjan van de Ven# 39*aa5d9151SArjan van de Ven 40*aa5d9151SArjan van de Venmy @rows; 41*aa5d9151SArjan van de Venmy %start, %end, %row; 42*aa5d9151SArjan van de Venmy $done = 0; 43*aa5d9151SArjan van de Venmy $rowcount = 0; 44*aa5d9151SArjan van de Venmy $maxtime = 0; 45*aa5d9151SArjan van de Venmy $count = 0; 46*aa5d9151SArjan van de Venwhile (<>) { 47*aa5d9151SArjan van de Ven my $line = $_; 48*aa5d9151SArjan van de Ven if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { 49*aa5d9151SArjan van de Ven my $func = $2; 50*aa5d9151SArjan van de Ven if ($done == 0) { 51*aa5d9151SArjan van de Ven $start{$func} = $1; 52*aa5d9151SArjan van de Ven } 53*aa5d9151SArjan van de Ven $row{$func} = 1; 54*aa5d9151SArjan van de Ven if ($line =~ /\@ ([0-9]+)/) { 55*aa5d9151SArjan van de Ven my $pid = $1; 56*aa5d9151SArjan van de Ven if (!defined($rows[$pid])) { 57*aa5d9151SArjan van de Ven $rowcount = $rowcount + 1; 58*aa5d9151SArjan van de Ven $rows[$pid] = $rowcount; 59*aa5d9151SArjan van de Ven } 60*aa5d9151SArjan van de Ven $row{$func} = $rows[$pid]; 61*aa5d9151SArjan van de Ven } 62*aa5d9151SArjan van de Ven $count = $count + 1; 63*aa5d9151SArjan van de Ven } 64*aa5d9151SArjan van de Ven 65*aa5d9151SArjan van de Ven if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) { 66*aa5d9151SArjan van de Ven if ($done == 0) { 67*aa5d9151SArjan van de Ven $end{$2} = $1; 68*aa5d9151SArjan van de Ven $maxtime = $1; 69*aa5d9151SArjan van de Ven } 70*aa5d9151SArjan van de Ven } 71*aa5d9151SArjan van de Ven if ($line =~ /Write protecting the/) { 72*aa5d9151SArjan van de Ven $done = 1; 73*aa5d9151SArjan van de Ven } 74*aa5d9151SArjan van de Ven} 75*aa5d9151SArjan van de Ven 76*aa5d9151SArjan van de Venif ($count == 0) { 77*aa5d9151SArjan van de Ven print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n"; 78*aa5d9151SArjan van de Ven print "that initcall_debug is passed on the kernel command line.\n\n"; 79*aa5d9151SArjan van de Ven print "Usage: \n"; 80*aa5d9151SArjan van de Ven print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; 81*aa5d9151SArjan van de Ven exit; 82*aa5d9151SArjan van de Ven} 83*aa5d9151SArjan van de Ven 84*aa5d9151SArjan van de Venprint "<?xml version=\"1.0\" standalone=\"no\"?> \n"; 85*aa5d9151SArjan van de Venprint "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"; 86*aa5d9151SArjan van de Ven 87*aa5d9151SArjan van de Venmy @styles; 88*aa5d9151SArjan van de Ven 89*aa5d9151SArjan van de Ven$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 90*aa5d9151SArjan van de Ven$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 91*aa5d9151SArjan van de Ven$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 92*aa5d9151SArjan van de Ven$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 93*aa5d9151SArjan van de Ven$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 94*aa5d9151SArjan van de Ven$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 95*aa5d9151SArjan van de Ven$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 96*aa5d9151SArjan van de Ven$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 97*aa5d9151SArjan van de Ven$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 98*aa5d9151SArjan van de Ven$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 99*aa5d9151SArjan van de Ven$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 100*aa5d9151SArjan van de Ven$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 101*aa5d9151SArjan van de Ven 102*aa5d9151SArjan van de Venmy $mult = 950.0 / $maxtime; 103*aa5d9151SArjan van de Venmy $threshold = 0.0500 / $maxtime; 104*aa5d9151SArjan van de Venmy $stylecounter = 0; 105*aa5d9151SArjan van de Venwhile (($key,$value) = each %start) { 106*aa5d9151SArjan van de Ven my $duration = $end{$key} - $start{$key}; 107*aa5d9151SArjan van de Ven 108*aa5d9151SArjan van de Ven if ($duration >= $threshold) { 109*aa5d9151SArjan van de Ven my $s, $s2, $e, $y; 110*aa5d9151SArjan van de Ven $s = $value * $mult; 111*aa5d9151SArjan van de Ven $s2 = $s + 6; 112*aa5d9151SArjan van de Ven $e = $end{$key} * $mult; 113*aa5d9151SArjan van de Ven $w = $e - $s; 114*aa5d9151SArjan van de Ven 115*aa5d9151SArjan van de Ven $y = $row{$key} * 150; 116*aa5d9151SArjan van de Ven $y2 = $y + 4; 117*aa5d9151SArjan van de Ven 118*aa5d9151SArjan van de Ven $style = $styles[$stylecounter]; 119*aa5d9151SArjan van de Ven $stylecounter = $stylecounter + 1; 120*aa5d9151SArjan van de Ven if ($stylecounter > 11) { 121*aa5d9151SArjan van de Ven $stylecounter = 0; 122*aa5d9151SArjan van de Ven }; 123*aa5d9151SArjan van de Ven 124*aa5d9151SArjan van de Ven print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n"; 125*aa5d9151SArjan van de Ven print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n"; 126*aa5d9151SArjan van de Ven } 127*aa5d9151SArjan van de Ven} 128*aa5d9151SArjan van de Ven 129*aa5d9151SArjan van de Ven 130*aa5d9151SArjan van de Ven# print the time line on top 131*aa5d9151SArjan van de Venmy $time = 0.0; 132*aa5d9151SArjan van de Venwhile ($time < $maxtime) { 133*aa5d9151SArjan van de Ven my $s2 = $time * $mult; 134*aa5d9151SArjan van de Ven print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n"; 135*aa5d9151SArjan van de Ven $time = $time + 0.1; 136*aa5d9151SArjan van de Ven} 137*aa5d9151SArjan van de Ven 138*aa5d9151SArjan van de Venprint "</svg>\n"; 139