Commit 509dd6a6 authored by Stefani Seibold's avatar Stefani Seibold Committed by James Toy

Changes since last posting:

 - fix compatibility with tools/perf/builtin-record.c in upstream kernel

The patch is against 2.6.30 and is tested on intel and ppc architectures.

ChangeLog:
 20. Jan 2009 V0.1
  - First Version for Kernel 2.6.28.1
 31. Mar 2009 V0.2
  - Ported to Kernel 2.6.29
 03. Jun 2009 V0.3
  - Ported to Kernel 2.6.30
  - Redesigned what was suggested by Ingo Molnar
  - the thread watch monitor is gone
  - the /proc/stackmon entry is also gone
  - slim down
 04. Jun 2009 V0.4
  - Redesigned everything that was suggested by Andrew Morton
  - slim down
 04. Jun 2009 V0.5
  - Code cleanup
 06. Jun 2009 V0.6
  - Fix missing mm->mmap_sem locking in function task_show_stack_usage()
  - Code cleanup
 10. Jun 2009 V0.7
  - update Documentation/filesystem/proc.txt
 10. Jun 2009 V0.8
  - change maps/smaps output, displays now the max. stack size
 24. Jun 2009 V0.9
  - use walk_page_range() to determinate the stack usage high water mark
  - include swapped pages to the stack usage high water mark count
 24. Jun 2009 V0.10
  - fix off by one bug
  - cleanup

 fs/exec.c                          |    2
 include/linux/sched.h              |    1
 kernel/fork.c                      |    2
Signed-off-by: default avatarStefani Seibold <stefani@seibold.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 76ad5485
...@@ -309,7 +309,7 @@ address perms offset dev inode pathname ...@@ -309,7 +309,7 @@ address perms offset dev inode pathname
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test 08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
0804a000-0806b000 rw-p 00000000 00:00 0 [heap] 0804a000-0806b000 rw-p 00000000 00:00 0 [heap]
a7cb1000-a7cb2000 ---p 00000000 00:00 0 a7cb1000-a7cb2000 ---p 00000000 00:00 0
a7cb2000-a7eb2000 rw-p 00000000 00:00 0 [thread stack: 001ff4b4] a7cb2000-a7eb2000 rw-p 00000000 00:00 0 [threadstack:001ff4b4]
a7eb2000-a7eb3000 ---p 00000000 00:00 0 a7eb2000-a7eb3000 ---p 00000000 00:00 0
a7eb3000-a7ed5000 rw-p 00000000 00:00 0 a7eb3000-a7ed5000 rw-p 00000000 00:00 0
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
...@@ -345,7 +345,7 @@ is not associated with a file: ...@@ -345,7 +345,7 @@ is not associated with a file:
[stack] = the stack of the main process [stack] = the stack of the main process
[vdso] = the "virtual dynamic shared object", [vdso] = the "virtual dynamic shared object",
the kernel system call handler the kernel system call handler
[thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size [threadstack:xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size
or if empty, the mapping is anonymous. or if empty, the mapping is anonymous.
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
#include <linux/pid_namespace.h> #include <linux/pid_namespace.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <linux/swapops.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -321,34 +322,67 @@ static inline void task_context_switch_counts(struct seq_file *m, ...@@ -321,34 +322,67 @@ static inline void task_context_switch_counts(struct seq_file *m,
p->nivcsw); p->nivcsw);
} }
static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma, struct stack_stats {
struct task_struct *p) struct vm_area_struct *vma;
unsigned long startpage;
unsigned long usage;
};
static int stack_usage_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long end, struct mm_walk *walk)
{ {
unsigned long i; struct stack_stats *ss = walk->private;
struct page *page; struct vm_area_struct *vma = ss->vma;
unsigned long stkpage; pte_t *pte, ptent;
spinlock_t *ptl;
int ret = 0;
stkpage = KSTK_ESP(p) & PAGE_MASK; pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
for (; addr != end; pte++, addr += PAGE_SIZE) {
ptent = *pte;
#ifdef CONFIG_STACK_GROWSUP #ifdef CONFIG_STACK_GROWSUP
for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) { if (pte_present(ptent) || is_swap_pte(ptent))
ss->usage = addr - ss->startpage + PAGE_SIZE;
page = follow_page(vma, i-PAGE_SIZE, 0); #else
if (pte_present(ptent) || is_swap_pte(ptent)) {
if (!IS_ERR(page) && page) ss->usage = ss->startpage - addr + PAGE_SIZE;
pte++;
ret = 1;
break; break;
}
#endif
} }
return i - (p->stack_start & PAGE_MASK); pte_unmap_unlock(pte - 1, ptl);
#else cond_resched();
for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) { return ret;
}
page = follow_page(vma, i, 0); static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
struct task_struct *task)
{
struct stack_stats ss;
struct mm_walk stack_walk = {
.pmd_entry = stack_usage_pte_range,
.mm = vma->vm_mm,
.private = &ss,
};
if (!IS_ERR(page) && page) if (!vma->vm_mm || is_vm_hugetlb_page(vma))
break; return 0;
}
return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE; ss.vma = vma;
ss.startpage = task->stack_start & PAGE_MASK;
ss.usage = 0;
#ifdef CONFIG_STACK_GROWSUP
walk_page_range(KSTK_ESP(task) & PAGE_MASK, vma->vm_end,
&stack_walk);
#else
walk_page_range(vma->vm_start, (KSTK_ESP(task) & PAGE_MASK) + PAGE_SIZE,
&stack_walk);
#endif #endif
return ss.usage;
} }
static inline void task_show_stack_usage(struct seq_file *m, static inline void task_show_stack_usage(struct seq_file *m,
......
...@@ -254,7 +254,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) ...@@ -254,7 +254,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
vma->vm_end >= stack_start) { vma->vm_end >= stack_start) {
pad_len_spaces(m, len); pad_len_spaces(m, len);
seq_printf(m, seq_printf(m,
"[thread stack: %08lx]", "[threadstack:%08lx]",
#ifdef CONFIG_STACK_GROWSUP #ifdef CONFIG_STACK_GROWSUP
vma->vm_end - stack_start vma->vm_end - stack_start
#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