#! /usr/bin/env stap
/*
* Copyright (C) 2009 Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Description: displays statistics for waiting and holding big kernel lock (BKL)
*
* Run: stap bkl_stats.stap
*
* Author: William Cohen
*/
global holder_time
global holder_stats, wait_stats
global names
probe begin { printf("biglock_stats running\n"); }
probe end, timer.s(5) {
print_stats()
}
function print_stats() {
# print out time waiting and time lock held
printf("big kernel lock waiting statistics\n");
printf("%-16s %6s %6s %6s %6s %6s\n",
"name", "tid", "count", "min", "avg", "max");
foreach (p+ in names) {
if (@count(wait_stats[p]))
printf("%16s %6d %6d %6d %6d %6d\n", names[p], p,
@count(wait_stats[p]), @min(wait_stats[p]),
@avg(wait_stats[p]), @max(wait_stats[p]));
}
printf("\n\nbig kernel lock holder statistics\n");
printf("%-16s %6s %6s %6s %6s %6s\n",
"name", "tid", "count", "min", "avg", "max");
foreach (p+ in names) {
if (@count(holder_stats[p]))
printf("%16s %6d %6d %6d %6d %6d\n", names[p], p,
@count(holder_stats[p]), @min(holder_stats[p]),
@avg(holder_stats[p]), @max(holder_stats[p]));
}
}
probe kernel.function("_lock_kernel").return!,
kernel.function("lock_kernel").return
{
t = gettimeofday_us()
s = @entry(gettimeofday_us())
holder_time[tid()] = t
# record the amount of time waiting for the lock
if (s) {
wait_stats[tid()] <<< t - s
names[tid()] = execname()
}
}
probe kernel.function("_unlock_kernel")!,
kernel.function("unlock_kernel")
{
t = gettimeofday_us()
s = holder_time[tid()]
holder_time[tid()] = t
# record the amount of time the process held the lock
if (s) {
holder_stats[tid()] <<< t - s
names[tid()] = execname()
}
}