Skip to content

Commit e18eecb

Browse files
cfd-36Linus Torvalds
authored andcommitted
Add generic exit-time stack-depth checking to CONFIG_DEBUG_STACK_USAGE
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>
1 parent 8481221 commit e18eecb

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

arch/um/Kconfig.debug

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,13 @@ config GCOV
4747
If you're involved in UML kernel development and want to use gcov,
4848
say Y. If you're unsure, say N.
4949

50+
config DEBUG_STACK_USAGE
51+
bool "Stack utilization instrumentation"
52+
default N
53+
help
54+
Track the maximum kernel stack usage - this will look at each
55+
kernel stack at process exit and log it if it's the deepest
56+
stack seen so far.
57+
58+
This option will slow down process creation and destruction somewhat.
5059
endmenu

arch/um/defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,4 @@ CONFIG_FORCED_INLINING=y
527527
# CONFIG_RCU_TORTURE_TEST is not set
528528
# CONFIG_GPROF is not set
529529
# CONFIG_GCOV is not set
530+
# CONFIG_DEBUG_STACK_USAGE is not set

include/asm-um/thread_info.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,19 @@ static inline struct thread_info *current_thread_info(void)
5252
return ti;
5353
}
5454

55+
#ifdef CONFIG_DEBUG_STACK_USAGE
56+
57+
#define alloc_thread_info(tsk) \
58+
((struct thread_info *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, \
59+
CONFIG_KERNEL_STACK_ORDER))
60+
#else
61+
5562
/* thread information allocation */
5663
#define alloc_thread_info(tsk) \
5764
((struct thread_info *) __get_free_pages(GFP_KERNEL, \
5865
CONFIG_KERNEL_STACK_ORDER))
66+
#endif
67+
5968
#define free_thread_info(ti) \
6069
free_pages((unsigned long)(ti),CONFIG_KERNEL_STACK_ORDER)
6170

kernel/exit.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,34 @@ static void exit_notify(struct task_struct *tsk)
858858
release_task(tsk);
859859
}
860860

861+
#ifdef CONFIG_DEBUG_STACK_USAGE
862+
static void check_stack_usage(void)
863+
{
864+
static DEFINE_SPINLOCK(low_water_lock);
865+
static int lowest_to_date = THREAD_SIZE;
866+
unsigned long *n = end_of_stack(current);
867+
unsigned long free;
868+
869+
while (*n == 0)
870+
n++;
871+
free = (unsigned long)n - (unsigned long)end_of_stack(current);
872+
873+
if (free >= lowest_to_date)
874+
return;
875+
876+
spin_lock(&low_water_lock);
877+
if (free < lowest_to_date) {
878+
printk(KERN_WARNING "%s used greatest stack depth: %lu bytes "
879+
"left\n",
880+
current->comm, free);
881+
lowest_to_date = free;
882+
}
883+
spin_unlock(&low_water_lock);
884+
}
885+
#else
886+
static inline void check_stack_usage(void) {}
887+
#endif
888+
861889
fastcall NORET_TYPE void do_exit(long code)
862890
{
863891
struct task_struct *tsk = current;
@@ -949,6 +977,7 @@ fastcall NORET_TYPE void do_exit(long code)
949977
exit_sem(tsk);
950978
__exit_files(tsk);
951979
__exit_fs(tsk);
980+
check_stack_usage();
952981
exit_thread();
953982
cpuset_exit(tsk);
954983
exit_keys(tsk);

0 commit comments

Comments
 (0)