Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e18eecb8 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

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: default avatarJeff Dike <jdike@linux.intel.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 84812217
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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)

+29 −0
Original line number Diff line number Diff line
@@ -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);