#!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0-only
# Copyright 2008, Intel Corporation
#
# This file is part of the Linux kernel
#
# Authors:
# Arjan van de Ven
#
# This script turns a dmesg output into a SVG graphic that shows which
# functions take how much time. You can view SVG graphics with various
# programs, including Inkscape, The Gimp and Firefox.
#
#
# For this script to work, the kernel needs to be compiled with the
# CONFIG_PRINTK_TIME configuration option enabled, and with
# "initcall_debug" passed on the kernel command line.
#
# usage:
# dmesg | perl scripts/bootgraph.pl > output.svg
#
use strict;
use Getopt::Long;
my $header = 0;
sub help {
my $text = << "EOM";
Usage:
1) dmesg | perl scripts/bootgraph.pl [OPTION] > output.svg
2) perl scripts/bootgraph.pl -h
Options:
-header Insert kernel version and date
EOM
my $std=shift;
if ($std == 1) {
print STDERR $text;
} else {
print $text;
}
exit;
}
GetOptions(
'h|help' =>\&help,
'header' =>\$header
);
my %start;
my %end;
my %type;
my $done = 0;
my $maxtime = 0;
my $firsttime = 99999;
my $count = 0;
my %pids;
my %pidctr;
my $headerstep = 20;
my $xheader = 15;
my $yheader = 25;
my $cyheader = 0;
while (<>) {
my $line = $_;
if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_\.]+)\+/) {
my $func = $2;
if ($done == 0) {
$start{$func} = $1;
$type{$func} = 0;
if ($1 < $firsttime) {
$firsttime = $1;
}
}
if ($line =~ /\@ ([0-9]+)/) {
$pids{$func} = $1;
}
$count = $count + 1;
}
if ($line =~ /([0-9\.]+)\] async_waiting @ ([0-9]+)/) {
my $pid = $2;
my $func;
if (!defined($pidctr{$pid})) {
$func = "wait_" . $pid . "_1";
$pidctr{$pid} = 1;
} else {
$pidctr{$pid} = $pidctr{$pid} + 1;
$func = "wait_" . $pid . "_" . $pidctr{$pid};
}
if ($done == 0) {
$start{$func} = $1;
$type{$func} = 1;
if ($1 < $firsttime) {
$firsttime = $1;
}
}
$pids{$func} = $pid;
$count = $count + 1;
}
if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_\.]+)\+.*returned/) {
if ($done == 0) {
$end{$2} = $1;
$maxtime = $1;
}
}
if ($line =~ /([0-9\.]+)\] async_continuing @ ([0-9]+)/) {
my $pid = $2;
my $func = "wait_" . $pid . "_" . $pidctr{$pid};
$end{$func} = $1;
$maxtime = $1;
}
if ($line =~ /Write protecting the/) {
$done = 1;
}
if ($line =~ /Freeing unused kernel memory/) {
$done = 1;
}
}
if ($count == 0) {
print STDERR < \n";
print "\n";