1*8a4f73aaSchristos#!/usr/pkg/bin/perl -w 2c29d5175Schristos# 3c29d5175Schristos# hotkernel - sample on-CPU kernel-level functions and modules. 4c29d5175Schristos# Written using Perl and DTrace (Solaris 10 03/05) 5c29d5175Schristos# 6c29d5175Schristos# This samples the on-CPU function at 1001 Hertz, for a simple yet 7c29d5175Schristos# effective kernel-level profiling tool for sampling exclusive function time. 8c29d5175Schristos# The output will identify which function is on the CPU the most - which is 9c29d5175Schristos# the hottest. See Notes/ALLexclusive_notes.txt for an explanation of 10c29d5175Schristos# exclusive time. 11c29d5175Schristos# 12*8a4f73aaSchristos# $Id: hotkernel,v 1.2 2016/12/12 16:30:03 christos Exp $ 13c29d5175Schristos# 14c29d5175Schristos# USAGE: hotkernel [-hm] 15c29d5175Schristos# 16c29d5175Schristos# -h # help 17c29d5175Schristos# -m # match modules, not functions 18c29d5175Schristos# eg, 19c29d5175Schristos# hotkernel # sample kernel functions 20c29d5175Schristos# hotkernel -m # sample kernel modules 21c29d5175Schristos# 22c29d5175Schristos# FIELDS: 23c29d5175Schristos# FUNCTION Function name 24c29d5175Schristos# MODULE Module name 25c29d5175Schristos# COUNT Number of samples 26c29d5175Schristos# PCNT Percentage of total samples 27c29d5175Schristos# 28c29d5175Schristos# COPYRIGHT: Copyright (c) 2006 Brendan Gregg. 29c29d5175Schristos# 30c29d5175Schristos# CDDL HEADER START 31c29d5175Schristos# 32c29d5175Schristos# The contents of this file are subject to the terms of the 33c29d5175Schristos# Common Development and Distribution License, Version 1.0 only 34c29d5175Schristos# (the "License"). You may not use this file except in compliance 35c29d5175Schristos# with the License. 36c29d5175Schristos# 37c29d5175Schristos# You can obtain a copy of the license at Docs/cddl1.txt 38c29d5175Schristos# or http://www.opensolaris.org/os/licensing. 39c29d5175Schristos# See the License for the specific language governing permissions 40c29d5175Schristos# and limitations under the License. 41c29d5175Schristos# 42c29d5175Schristos# CDDL HEADER END 43c29d5175Schristos# 44c29d5175Schristos# Author: Brendan Gregg [Sydney, Australia] 45c29d5175Schristos# 46c29d5175Schristos# 29-Jun-2006 Brendan Gregg Created this. 47c29d5175Schristos# 29-Jun-2006 " " Last update. 48c29d5175Schristos# 49c29d5175Schristos 50c29d5175Schristosuse strict; 51c29d5175Schristosuse Getopt::Std; 52c29d5175Schristos 53c29d5175Schristos# 54c29d5175Schristos# Command Line Arguments 55c29d5175Schristos# 56c29d5175Schristosmy $args; 57c29d5175Schristosusage() if defined $ARGV[0] and $ARGV[0] eq "--help"; 58c29d5175Schristosgetopts('hm') or usage(); 59c29d5175Schristosusage() if defined $main::opt_h and $main::opt_h; 60c29d5175Schristosmy $mods = defined $main::opt_m and $main::opt_m ? 1 : 0; 61c29d5175Schristos 62c29d5175Schristos# 63c29d5175Schristos# Cleanup on signals 64c29d5175Schristos# 65c29d5175Schristos$SIG{INT} = \&cleanupsig; # Ctrl-C 66c29d5175Schristos$SIG{QUIT} = \&cleanupsig; # Ctrl-\ 67c29d5175Schristos$SIG{TERM} = \&cleanupsig; # TERM 68c29d5175Schristos 69c29d5175Schristos# 70c29d5175Schristos# Declare DTrace script 71c29d5175Schristos# 72c29d5175Schristosmy $dtrace = <<END; 73c29d5175Schristos/usr/sbin/dtrace -n ' 74c29d5175Schristos #pragma D option quiet 75c29d5175Schristos profile:::profile-1001hz 76c29d5175Schristos /arg0/ 77c29d5175Schristos { 78c29d5175Schristos \@pc[arg0] = count(); 79c29d5175Schristos } 80c29d5175Schristos dtrace:::END 81c29d5175Schristos { 82c29d5175Schristos printa("%a %\@d\\n", \@pc); 83c29d5175Schristos } 84c29d5175Schristos' 85c29d5175SchristosEND 86c29d5175Schristos 87c29d5175Schristos# 88c29d5175Schristos# Run DTrace, process output 89c29d5175Schristos# 90c29d5175Schristosmy %Count; 91c29d5175Schristosmy $total; 92c29d5175Schristosopen DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n"; 93c29d5175Schristosprint "Sampling... Hit Ctrl-C to end.\n"; 94c29d5175Schristoswhile (my $line = <DTRACE>) { 95c29d5175Schristos next if $line =~ /^\s*$/; 96c29d5175Schristos my ($addr, $count) = split ' ', $line; 97c29d5175Schristos my ($name, $offset) = split /\+/, $addr; 98c29d5175Schristos next if $name eq "0x0"; 99c29d5175Schristos $name =~ s/\`.*// if $mods; 100c29d5175Schristos $Count{$name} += $count; 101c29d5175Schristos $total += $count; 102c29d5175Schristos} 103c29d5175Schristosclose DTRACE; 104c29d5175Schristos 105c29d5175Schristos# 106c29d5175Schristos# Print final report 107c29d5175Schristos# 108c29d5175Schristosprintf "\n%-52s %8s %6s\n", $mods ? "MODULE" : "FUNCTION", "COUNT", "PCNT"; 109c29d5175Schristosforeach my $name (sort { $Count{$a} <=> $Count{$b} } keys %Count) { 110c29d5175Schristos printf "%-52s %8d %5.1f%%\n", $name, $Count{$name}, 111c29d5175Schristos 100 * $Count{$name} / ($total ? $total : 1); 112c29d5175Schristos} 113c29d5175Schristos 114c29d5175Schristos# 115c29d5175Schristos# Subroutines 116c29d5175Schristos# 117c29d5175Schristossub cleanupsig { 118c29d5175Schristos} 119c29d5175Schristossub usage { 120c29d5175Schristos print STDERR "USAGE: hotkernel [-hm]\n"; 121c29d5175Schristos print STDERR " eg,\n"; 122c29d5175Schristos print STDERR " hotkernel # sample kernel functions\n"; 123c29d5175Schristos print STDERR " hotkernel -m # sample kernel modules\n"; 124c29d5175Schristos exit 1; 125c29d5175Schristos} 126