Skip to content

Commit

Permalink
Add generic exit-time stack-depth checking to CONFIG_DEBUG_STACK_USAGE
Browse files Browse the repository at this point in the history
Add generic exit-time stack-depth checking to CONFIG_DEBUG_STACK_USAGE.

This also adds UML support.

Tested on UML and i386.

[akpm@linux-foundation.org: cleanups, speedups, tweaks]
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Jeff Dike authored and Linus Torvalds committed Jul 16, 2007
1 parent 8481221 commit e18eecb
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
9 changes: 9 additions & 0 deletions arch/um/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,13 @@ config GCOV
If you're involved in UML kernel development and want to use gcov,
say Y. If you're unsure, say N.

config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
default N
help
Track the maximum kernel stack usage - this will look at each
kernel stack at process exit and log it if it's the deepest
stack seen so far.

This option will slow down process creation and destruction somewhat.
endmenu
1 change: 1 addition & 0 deletions arch/um/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,4 @@ CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
# CONFIG_DEBUG_STACK_USAGE is not set
9 changes: 9 additions & 0 deletions include/asm-um/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,19 @@ static inline struct thread_info *current_thread_info(void)
return ti;
}

#ifdef CONFIG_DEBUG_STACK_USAGE

#define alloc_thread_info(tsk) \
((struct thread_info *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, \
CONFIG_KERNEL_STACK_ORDER))
#else

/* thread information allocation */
#define alloc_thread_info(tsk) \
((struct thread_info *) __get_free_pages(GFP_KERNEL, \
CONFIG_KERNEL_STACK_ORDER))
#endif

#define free_thread_info(ti) \
free_pages((unsigned long)(ti),CONFIG_KERNEL_STACK_ORDER)

Expand Down
29 changes: 29 additions & 0 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,34 @@ static void exit_notify(struct task_struct *tsk)
release_task(tsk);
}

#ifdef CONFIG_DEBUG_STACK_USAGE
static void check_stack_usage(void)
{
static DEFINE_SPINLOCK(low_water_lock);
static int lowest_to_date = THREAD_SIZE;
unsigned long *n = end_of_stack(current);
unsigned long free;

while (*n == 0)
n++;
free = (unsigned long)n - (unsigned long)end_of_stack(current);

if (free >= lowest_to_date)
return;

spin_lock(&low_water_lock);
if (free < lowest_to_date) {
printk(KERN_WARNING "%s used greatest stack depth: %lu bytes "
"left\n",
current->comm, free);
lowest_to_date = free;
}
spin_unlock(&low_water_lock);
}
#else
static inline void check_stack_usage(void) {}
#endif

fastcall NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
Expand Down Expand Up @@ -949,6 +977,7 @@ fastcall NORET_TYPE void do_exit(long code)
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
check_stack_usage();
exit_thread();
cpuset_exit(tsk);
exit_keys(tsk);
Expand Down

0 comments on commit e18eecb

Please sign in to comment.