blob: 42a6d152508a2e7f60076825cbb9d53b45568c70 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#!/usr/bin/perl
#
# This script accumulates the execution paths of all calls to kmalloc
# in the kernel. On Ctrl-C, it sorts, filters and displays them on
# stdout.
#
# The -e (exclude) option can be used to specify a comma-separated list
# - any stack with contents matching any of the items in the list will
# be excluded from the output.
#
# The -m (min) option can be used to specify the minimum number of
# occurrences a stack needs to be included in the output.
#
# Usage: ./kmalloc-top [-m min] [-i exclude list]
# Ctrl-c
use Getopt::Std;
my $kmalloc_stacks;
my $total_kmallocs;
my $sorted_stacks;
my $min_count = 1;
my $exclude;
$SIG{INT} = \&sigint_handler;
getopts('e:m:');
if ($opt_e) {
$exclude = join('|', split(/,/, $opt_e));
print "Will exclude stacks containing: $exclude\n";
}
if ($opt_m) {
$min_count = $opt_n;
}
print "Will print stacks with counts >= $min_count.\n";
print STDERR "Press Ctrl-C to stop.\n";
open STREAM, "stap -g kmalloc-stacks.stp |" or die "Couldn't get output stream $!";
while (<STREAM>) {
if (/<hashval>(.*?)<\/hashval>/) {
update_hash($key, $1);
$key = "";
} elsif ($_ !~ (/<hashkey>|<\/hashkey>/)) {
$key .= $_;
}
}
$num_keys_before_filtering = scalar keys %kmalloc_stacks;
filter_stacks();
$num_keys_after_filtering = scalar keys %kmalloc_stacks;
sort_stacks();
summarize();
exit();
sub update_hash
{
my($key, $val) = @_;
$kmalloc_stacks{$key} += $val;
$total_kmallocs += $val;
}
sub filter_stacks
{
while (($stack, $count) = each %kmalloc_stacks) {
if ($count < $min_count) {
delete $kmalloc_stacks{$stack};
} elsif ($exclude && $stack =~ /$exclude/) {
delete $kmalloc_stacks{$stack};
}
}
}
sub sort_stacks
{
@sorted_stacks = sort { $kmalloc_stacks{$b} <=> $kmalloc_stacks{$a} } keys %kmalloc_stacks;
}
sub summarize {
print "\n";
foreach $stack(@sorted_stacks) {
print "This path seen $kmalloc_stacks{$stack} times:\n$stack\n";
}
print "Total kmallocs (before filtering): $total_kmallocs\n";
print "Num stacks before filtering: $num_keys_before_filtering\n";
print "Num stacks after filtering: $num_keys_after_filtering\n";
close(STREAM);
}
sub sigint_handler
{
system("pkill kmalloc-stacks");
}
|