diff options
| author | Jeff Dike <jdike@addtoit.com> | 2007-07-15 23:38:48 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 09:05:38 -0700 | 
| commit | e18eecb8b35703a5eea73ee2b45324262029e62c (patch) | |
| tree | 8c276ae6633b8116ca366274091b00491fd50bbe | |
| parent | 84812217e395f5272eac36856c0a2415d61fe139 (diff) | |
| download | olio-linux-3.10-e18eecb8b35703a5eea73ee2b45324262029e62c.tar.xz olio-linux-3.10-e18eecb8b35703a5eea73ee2b45324262029e62c.zip  | |
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>
| -rw-r--r-- | arch/um/Kconfig.debug | 9 | ||||
| -rw-r--r-- | arch/um/defconfig | 1 | ||||
| -rw-r--r-- | include/asm-um/thread_info.h | 9 | ||||
| -rw-r--r-- | kernel/exit.c | 29 | 
4 files changed, 48 insertions, 0 deletions
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index 09c1aca6339..c86f5eb29fd 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -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 diff --git a/arch/um/defconfig b/arch/um/defconfig index a54d0efecae..e5b2df9e12d 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -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 diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h index 07aa4e50e4d..6e5fd5c892d 100644 --- a/include/asm-um/thread_info.h +++ b/include/asm-um/thread_info.h @@ -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) diff --git a/kernel/exit.c b/kernel/exit.c index ca6a11b7302..64a5263c8c7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -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; @@ -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);  |