Commit 416cd06a authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix the display of max-ever-used-stack in sysrq-T output

The sysrq-T output currently tries to display the mimimum amount of free
stack which each task has ever had available.  It has been busted for years,
because we forgot to zero out the stack when it is first created.

Fix that up, adding a conig option for it.

If the option is disabled, or the arch is not x86 then the free stack usage
will display as zero.
parent d7790f20
...@@ -1232,6 +1232,15 @@ config DEBUG_STACKOVERFLOW ...@@ -1232,6 +1232,15 @@ config DEBUG_STACKOVERFLOW
bool "Check for stack overflows" bool "Check for stack overflows"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
depends on DEBUG_KERNEL
help
Enables the display of the minimum amount of free stack which each
task has ever had available in the sysrq-T and sysrq-P debug output.
This option will slow down process creation somewhat.
config DEBUG_SLAB config DEBUG_SLAB
bool "Debug memory allocations" bool "Debug memory allocations"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
......
...@@ -88,7 +88,20 @@ static inline struct thread_info *current_thread_info(void) ...@@ -88,7 +88,20 @@ static inline struct thread_info *current_thread_info(void)
} }
/* thread information allocation */ /* thread information allocation */
#define alloc_thread_info(task) ((struct thread_info *)kmalloc(THREAD_SIZE, GFP_KERNEL)) #ifdef CONFIG_DEBUG_STACK_USAGE
#define alloc_thread_info(tsk) \
({ \
struct thread_info *ret; \
\
ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \
if (ret) \
memset(ret, 0, THREAD_SIZE); \
ret; \
})
#else
#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
#endif
#define free_thread_info(info) kfree(info) #define free_thread_info(info) kfree(info)
#define get_thread_info(ti) get_task_struct((ti)->task) #define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task)
......
...@@ -2571,6 +2571,7 @@ static void show_task(task_t * p) ...@@ -2571,6 +2571,7 @@ static void show_task(task_t * p)
{ {
task_t *relative; task_t *relative;
unsigned state; unsigned state;
unsigned long free = 0;
static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" }; static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
printk("%-13.13s ", p->comm); printk("%-13.13s ", p->comm);
...@@ -2590,7 +2591,15 @@ static void show_task(task_t * p) ...@@ -2590,7 +2591,15 @@ static void show_task(task_t * p)
else else
printk(" %016lx ", thread_saved_pc(p)); printk(" %016lx ", thread_saved_pc(p));
#endif #endif
printk("%5d %6d ", p->pid, p->parent->pid); #ifdef CONFIG_DEBUG_STACK_USAGE
{
unsigned long * n = (unsigned long *) (p->thread_info+1);
while (!*n)
n++;
free = (unsigned long) n - (unsigned long)(p->thread_info+1);
}
#endif
printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
if ((relative = eldest_child(p))) if ((relative = eldest_child(p)))
printk("%5d ", relative->pid); printk("%5d ", relative->pid);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment