From 10715a018760e1d862b8348e31dc505e832a0904 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Sat, 11 Jun 2011 22:48:49 -0700 Subject: [PATCH] Add default stack checking When your kernel is built with kernel stack tracing enabled and you have the debugfs filesystem mounted. Then the zfs.sh script will clear the worst observed kernel stack depth on module load and check the worst case usage on module removal. If the stack depth ever exceeds 7000 bytes the full stack will be printed for debugging. This is dangerously close to overrunning the default 8k stack. This additional advisory debugging is particularly valuable when running the regression tests on a kernel built with 16k stacks. In this case, almost no matter how bad the stack overrun is you will see be able to get a clean stack trace for debugging. Since the worst case stack usage can be highly variable it's helpful to always check the worst case usage. --- scripts/common.sh.in | 26 ++++++++++++++++++++++++++ scripts/zfs.sh | 2 ++ 2 files changed, 28 insertions(+) diff --git a/scripts/common.sh.in b/scripts/common.sh.in index cf55859450..51671ebc01 100644 --- a/scripts/common.sh.in +++ b/scripts/common.sh.in @@ -635,3 +635,29 @@ wait_udev() { return 0 } + +stack_clear() { + local STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size + local STACK_TRACER_ENABLED=/proc/sys/kernel/stack_tracer_enabled + + if [ -e $STACK_MAX_SIZE ]; then + echo 1 >$STACK_TRACER_ENABLED + echo 0 >$STACK_MAX_SIZE + fi +} + +stack_check() { + local STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size + local STACK_TRACE=/sys/kernel/debug/tracing/stack_trace + local STACK_LIMIT=7000 + + if [ -e $STACK_MAX_SIZE ]; then + STACK_SIZE=`cat $STACK_MAX_SIZE` + + if [ $STACK_SIZE -ge $STACK_LIMIT ]; then + echo + echo "Warning: max stack size $STACK_SIZE bytes" + cat $STACK_TRACE + fi + fi +} diff --git a/scripts/zfs.sh b/scripts/zfs.sh index 4a707fabf3..f44053e888 100755 --- a/scripts/zfs.sh +++ b/scripts/zfs.sh @@ -66,8 +66,10 @@ fi if [ ${UNLOAD} ]; then umount -t zfs -a + stack_check unload_modules else + stack_clear check_modules || die "${ERROR}" load_modules "$@" wait_udev /dev/zfs 30