All of lore.kernel.org
 help / color / mirror / Atom feed
* Detailed Stack Information Patch [1/3]
@ 2009-03-31 14:58 ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-03-31 14:58 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Peter Zijlstra, Ingo Molnar, Joerg Engel

diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
--- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
@@ -1336,6 +1336,10 @@
 	if (retval < 0)
 		goto out;
 
+#ifdef CONFIG_PROC_STACK
+	current->stack_start = current->mm->start_stack;
+#endif
+
 	/* execve succeeded */
 	mutex_unlock(&current->cred_exec_mutex);
 	acct_update_integrals(current);
diff -u -N -r linux-2.6.29.orig/fs/proc/array.c linux-2.6.29/fs/proc/array.c
--- linux-2.6.29.orig/fs/proc/array.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/proc/array.c	2009-03-31 16:00:19.000000000 +0200
@@ -320,6 +320,25 @@
 			p->nivcsw);
 }
 
+#ifdef CONFIG_PROC_STACK
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	unsigned long		cur_stack;
+	unsigned long		base_page;
+
+	base_page = KSTK_ESP(p) >> PAGE_SHIFT;
+
+#ifdef CONFIG_STACK_GROWSUP
+	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
+#else
+	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
+#endif
+	seq_printf(m,	"stack usage:\t%lu kB\n",
+		(cur_stack + 1) << (PAGE_SHIFT-10));
+}
+#endif
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -339,6 +358,9 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+#ifdef CONFIG_PROC_STACK
+	task_show_stack_usage(m, task);
+#endif
 	return 0;
 }
 
diff -u -N -r linux-2.6.29.orig/fs/proc/task_mmu.c linux-2.6.29/fs/proc/task_mmu.c
--- linux-2.6.29.orig/fs/proc/task_mmu.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/proc/task_mmu.c	2009-03-31 16:00:19.000000000 +0200
@@ -240,6 +240,18 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+#ifdef CONFIG_PROC_STACK
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						 m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start && 
+					    vma->vm_end >= stack_start)
+						name="[thread stack]";
+#endif
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.29.orig/include/linux/sched.h linux-2.6.29/include/linux/sched.h
--- linux-2.6.29.orig/include/linux/sched.h	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/include/linux/sched.h	2009-03-31 16:00:45.000000000 +0200
@@ -1417,6 +1417,9 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+#ifdef CONFIG_PROC_STACK
+	unsigned long stack_start;
+#endif
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.29.orig/init/Kconfig linux-2.6.29/init/Kconfig
--- linux-2.6.29.orig/init/Kconfig	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/init/Kconfig	2009-03-31 16:00:19.000000000 +0200
@@ -952,6 +952,18 @@
 
 source "arch/Kconfig"
 
+config PROC_STACK
+ 	default y
+	depends on PROC_FS && MMU
+	bool "Enable /proc/<pid> stack monitoring" if EMBEDDED
+ 	help
+	  This enables monitoring of process and thread stack utilization.
+
+	  The /proc/pid/maps, /proc/pid/smaps, /proc/pid/status and the
+	  /proc/pid/task/pid pedants will be extended by the stack information.
+	  Disabling these interfaces will reduce the size of the kernel by
+	  approximately 1kb.
+
 endmenu		# General setup
 
 config HAVE_GENERIC_DMA_COHERENT
diff -u -N -r linux-2.6.29.orig/kernel/fork.c linux-2.6.29/kernel/fork.c
--- linux-2.6.29.orig/kernel/fork.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/kernel/fork.c	2009-03-31 16:00:19.000000000 +0200
@@ -1098,6 +1098,11 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+#ifdef CONFIG_PROC_STACK
+	p->stack_start = (stack_start == KSTK_ESP(current)) ?
+		current->stack_start : stack_start;
+#endif
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Detailed Stack Information Patch [1/3]
@ 2009-03-31 14:58 ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-03-31 14:58 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Peter Zijlstra, Ingo Molnar, Joerg Engel

diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
--- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
@@ -1336,6 +1336,10 @@
 	if (retval < 0)
 		goto out;
 
+#ifdef CONFIG_PROC_STACK
+	current->stack_start = current->mm->start_stack;
+#endif
+
 	/* execve succeeded */
 	mutex_unlock(&current->cred_exec_mutex);
 	acct_update_integrals(current);
diff -u -N -r linux-2.6.29.orig/fs/proc/array.c linux-2.6.29/fs/proc/array.c
--- linux-2.6.29.orig/fs/proc/array.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/proc/array.c	2009-03-31 16:00:19.000000000 +0200
@@ -320,6 +320,25 @@
 			p->nivcsw);
 }
 
+#ifdef CONFIG_PROC_STACK
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	unsigned long		cur_stack;
+	unsigned long		base_page;
+
+	base_page = KSTK_ESP(p) >> PAGE_SHIFT;
+
+#ifdef CONFIG_STACK_GROWSUP
+	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
+#else
+	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
+#endif
+	seq_printf(m,	"stack usage:\t%lu kB\n",
+		(cur_stack + 1) << (PAGE_SHIFT-10));
+}
+#endif
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -339,6 +358,9 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+#ifdef CONFIG_PROC_STACK
+	task_show_stack_usage(m, task);
+#endif
 	return 0;
 }
 
diff -u -N -r linux-2.6.29.orig/fs/proc/task_mmu.c linux-2.6.29/fs/proc/task_mmu.c
--- linux-2.6.29.orig/fs/proc/task_mmu.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/fs/proc/task_mmu.c	2009-03-31 16:00:19.000000000 +0200
@@ -240,6 +240,18 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+#ifdef CONFIG_PROC_STACK
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						 m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start && 
+					    vma->vm_end >= stack_start)
+						name="[thread stack]";
+#endif
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.29.orig/include/linux/sched.h linux-2.6.29/include/linux/sched.h
--- linux-2.6.29.orig/include/linux/sched.h	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/include/linux/sched.h	2009-03-31 16:00:45.000000000 +0200
@@ -1417,6 +1417,9 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+#ifdef CONFIG_PROC_STACK
+	unsigned long stack_start;
+#endif
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.29.orig/init/Kconfig linux-2.6.29/init/Kconfig
--- linux-2.6.29.orig/init/Kconfig	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/init/Kconfig	2009-03-31 16:00:19.000000000 +0200
@@ -952,6 +952,18 @@
 
 source "arch/Kconfig"
 
+config PROC_STACK
+ 	default y
+	depends on PROC_FS && MMU
+	bool "Enable /proc/<pid> stack monitoring" if EMBEDDED
+ 	help
+	  This enables monitoring of process and thread stack utilization.
+
+	  The /proc/pid/maps, /proc/pid/smaps, /proc/pid/status and the
+	  /proc/pid/task/pid pedants will be extended by the stack information.
+	  Disabling these interfaces will reduce the size of the kernel by
+	  approximately 1kb.
+
 endmenu		# General setup
 
 config HAVE_GENERIC_DMA_COHERENT
diff -u -N -r linux-2.6.29.orig/kernel/fork.c linux-2.6.29/kernel/fork.c
--- linux-2.6.29.orig/kernel/fork.c	2009-03-24 00:12:14.000000000 +0100
+++ linux-2.6.29/kernel/fork.c	2009-03-31 16:00:19.000000000 +0200
@@ -1098,6 +1098,11 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+#ifdef CONFIG_PROC_STACK
+	p->stack_start = (stack_start == KSTK_ESP(current)) ?
+		current->stack_start : stack_start;
+#endif
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch [1/3]
  2009-03-31 14:58 ` Stefani Seibold
@ 2009-04-01 19:31   ` Ingo Molnar
  -1 siblings, 0 replies; 57+ messages in thread
From: Ingo Molnar @ 2009-04-01 19:31 UTC (permalink / raw)
  To: Stefani Seibold, Andrew Morton
  Cc: linux-kernel, linux-mm, Peter Zijlstra, Joerg Engel, Thomas Gleixner


* Stefani Seibold <stefani@seibold.net> wrote:

> diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
> --- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
> +++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
> @@ -1336,6 +1336,10 @@
>  	if (retval < 0)
>  		goto out;
>  
> +#ifdef CONFIG_PROC_STACK
> +	current->stack_start = current->mm->start_stack;
> +#endif

Ok. The 1/3 patch, the whole "display where the stack is" thing is 
obviously useful and we know that.

Today we display this:

 earth4:~/tip> cat /proc/self/maps 
 00110000-00111000 r-xp 00110000 00:00 0          [vdso]
 0053e000-0055e000 r-xp 00000000 09:00 54591597   /lib/ld-2.9.so
 0055f000-00560000 r--p 00020000 09:00 54591597   /lib/ld-2.9.so
 00560000-00561000 rw-p 00021000 09:00 54591597   /lib/ld-2.9.so
 00563000-006d1000 r-xp 00000000 09:00 54591620   /lib/libc-2.9.so
 006d1000-006d3000 r--p 0016e000 09:00 54591620   /lib/libc-2.9.so
 006d3000-006d4000 rw-p 00170000 09:00 54591620   /lib/libc-2.9.so
 006d4000-006d7000 rw-p 006d4000 00:00 0 
 08048000-08054000 r-xp 00000000 09:00 27787363   /bin/cat
 08054000-08055000 rw-p 0000c000 09:00 27787363   /bin/cat
 09996000-099b7000 rw-p 09996000 00:00 0          [heap]
 b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
 b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
 bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack]

I was the one who added the [stack], [heap] and [vdso] annotations a 
few years ago and user-space developers liked it very much.

Tools parsing these files wont break [they dont care about the final 
column] - so there's no ABI worries and we can certainly do more 
here and enhance it.

You extend the above output with (in essence):

> +#ifdef CONFIG_PROC_STACK
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)

It would be better to put this into a fresh, related feature that 
went upstream recently:

 spirit:~> cat /proc/self/stack
 [<ffffffff8101c333>] save_stack_trace_tsk+0x26/0x43
 [<ffffffff81129237>] proc_pid_stack+0x63/0xa1
 [<ffffffff8112a753>] proc_single_show+0x5c/0x79
 [<ffffffff810fb2d6>] seq_read+0x16f/0x34d
 [<ffffffff810e3eea>] vfs_read+0xab/0x108
 [<ffffffff810e4007>] sys_read+0x4a/0x6e
 [<ffffffff8101133a>] system_call_fastpath+0x16/0x1b
 [<ffffffffffffffff>] 0xffffffffffffffff

That displays the kernel stack data - and we could display 
information about the user-stack data as well.

This #ifdef:

> +#ifdef CONFIG_STACK_GROWSUP
> +	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
> +#else
> +	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
> +#endif

Should be hidden in a task_user_stack() inline helper.

Another thing is:

> @@ -240,6 +240,18 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +#ifdef CONFIG_PROC_STACK
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						 m->private)->task->stack_start;
> +
> +					if (vma->vm_start <= stack_start && 
> +					    vma->vm_end >= stack_start)
> +						name="[thread stack]";
> +#endif

This too should be unconditional IMO (it's useful, and 
ultra-embedded systems worried about kernel .text size can turn off 
CONFIG_PROC_FS anyway), _and_ i think we could do even better.

How about extending /proc/X/maps with:

 b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
 b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
 bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack, usage: 1391 kB]

This is deterministically parseable, and meaningful-at-a-glance. 
Similarly for 'thread stack'.

This way we dont need any new files in /proc - that just increases 
the per task memory overhead.

What do you think?

	Ingo

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch [1/3]
@ 2009-04-01 19:31   ` Ingo Molnar
  0 siblings, 0 replies; 57+ messages in thread
From: Ingo Molnar @ 2009-04-01 19:31 UTC (permalink / raw)
  To: Stefani Seibold, Andrew Morton
  Cc: linux-kernel, linux-mm, Peter Zijlstra, Joerg Engel, Thomas Gleixner


* Stefani Seibold <stefani@seibold.net> wrote:

> diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
> --- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
> +++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
> @@ -1336,6 +1336,10 @@
>  	if (retval < 0)
>  		goto out;
>  
> +#ifdef CONFIG_PROC_STACK
> +	current->stack_start = current->mm->start_stack;
> +#endif

Ok. The 1/3 patch, the whole "display where the stack is" thing is 
obviously useful and we know that.

Today we display this:

 earth4:~/tip> cat /proc/self/maps 
 00110000-00111000 r-xp 00110000 00:00 0          [vdso]
 0053e000-0055e000 r-xp 00000000 09:00 54591597   /lib/ld-2.9.so
 0055f000-00560000 r--p 00020000 09:00 54591597   /lib/ld-2.9.so
 00560000-00561000 rw-p 00021000 09:00 54591597   /lib/ld-2.9.so
 00563000-006d1000 r-xp 00000000 09:00 54591620   /lib/libc-2.9.so
 006d1000-006d3000 r--p 0016e000 09:00 54591620   /lib/libc-2.9.so
 006d3000-006d4000 rw-p 00170000 09:00 54591620   /lib/libc-2.9.so
 006d4000-006d7000 rw-p 006d4000 00:00 0 
 08048000-08054000 r-xp 00000000 09:00 27787363   /bin/cat
 08054000-08055000 rw-p 0000c000 09:00 27787363   /bin/cat
 09996000-099b7000 rw-p 09996000 00:00 0          [heap]
 b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
 b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
 bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack]

I was the one who added the [stack], [heap] and [vdso] annotations a 
few years ago and user-space developers liked it very much.

Tools parsing these files wont break [they dont care about the final 
column] - so there's no ABI worries and we can certainly do more 
here and enhance it.

You extend the above output with (in essence):

> +#ifdef CONFIG_PROC_STACK
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)

It would be better to put this into a fresh, related feature that 
went upstream recently:

 spirit:~> cat /proc/self/stack
 [<ffffffff8101c333>] save_stack_trace_tsk+0x26/0x43
 [<ffffffff81129237>] proc_pid_stack+0x63/0xa1
 [<ffffffff8112a753>] proc_single_show+0x5c/0x79
 [<ffffffff810fb2d6>] seq_read+0x16f/0x34d
 [<ffffffff810e3eea>] vfs_read+0xab/0x108
 [<ffffffff810e4007>] sys_read+0x4a/0x6e
 [<ffffffff8101133a>] system_call_fastpath+0x16/0x1b
 [<ffffffffffffffff>] 0xffffffffffffffff

That displays the kernel stack data - and we could display 
information about the user-stack data as well.

This #ifdef:

> +#ifdef CONFIG_STACK_GROWSUP
> +	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
> +#else
> +	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
> +#endif

Should be hidden in a task_user_stack() inline helper.

Another thing is:

> @@ -240,6 +240,18 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +#ifdef CONFIG_PROC_STACK
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						 m->private)->task->stack_start;
> +
> +					if (vma->vm_start <= stack_start && 
> +					    vma->vm_end >= stack_start)
> +						name="[thread stack]";
> +#endif

This too should be unconditional IMO (it's useful, and 
ultra-embedded systems worried about kernel .text size can turn off 
CONFIG_PROC_FS anyway), _and_ i think we could do even better.

How about extending /proc/X/maps with:

 b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
 b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
 bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack, usage: 1391 kB]

This is deterministically parseable, and meaningful-at-a-glance. 
Similarly for 'thread stack'.

This way we dont need any new files in /proc - that just increases 
the per task memory overhead.

What do you think?

	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch [1/3]
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-04-02 21:26     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-04-02 21:26 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Andrew Morton, linux-kernel, linux-mm, Peter Zijlstra,
	Joerg Engel, Thomas Gleixner

Am Mittwoch, den 01.04.2009, 21:31 +0200 schrieb Ingo Molnar:
> * Stefani Seibold <stefani@seibold.net> wrote:
> 
> > diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
> > --- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
> > +++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
> > @@ -1336,6 +1336,10 @@
> >  	if (retval < 0)
> >  		goto out;
> >  
> > +#ifdef CONFIG_PROC_STACK
> > +	current->stack_start = current->mm->start_stack;
> > +#endif
> 
> Ok. The 1/3 patch, the whole "display where the stack is" thing is 
> obviously useful and we know that.
> 
> Today we display this:
> 
>  earth4:~/tip> cat /proc/self/maps 
>  00110000-00111000 r-xp 00110000 00:00 0          [vdso]
>  0053e000-0055e000 r-xp 00000000 09:00 54591597   /lib/ld-2.9.so
>  .
>  .
>  .
>  bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack]
> 
> I was the one who added the [stack], [heap] and [vdso] annotations a 
> few years ago and user-space developers liked it very much.
> 
> Tools parsing these files wont break [they dont care about the final 
> column] - so there's no ABI worries and we can certainly do more 
> here and enhance it.
> 
> You extend the above output with (in essence):
> 
> > +#ifdef CONFIG_PROC_STACK
> > +static inline void task_show_stack_usage(struct seq_file *m,
> > +						struct task_struct *p)
> 
> It would be better to put this into a fresh, related feature that 
> went upstream recently:
> 
>  spirit:~> cat /proc/self/stack
>  [<ffffffff8101c333>] save_stack_trace_tsk+0x26/0x43
>  .
>  .
>  .
> That displays the kernel stack data - and we could display 
> information about the user-stack data as well.
> 

/proc/self/stack is a good place for a more detailed information,
like the start address of the stack, the current usage and the highest
used address.

> This #ifdef:
> 
> > +#ifdef CONFIG_STACK_GROWSUP
> > +	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
> > +#else
> > +	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
> > +#endif
> 
> Should be hidden in a task_user_stack() inline helper.
> 

Yes, this is more readable.

> Another thing is:
> 
> > @@ -240,6 +240,18 @@
> >  				} else if (vma->vm_start <= mm->start_stack &&
> >  					   vma->vm_end >= mm->start_stack) {
> >  					name = "[stack]";
> > +#ifdef CONFIG_PROC_STACK
> > +				} else {
> > +					unsigned long stack_start;
> > +
> > +					stack_start =
> > +						((struct proc_maps_private *)
> > +						 m->private)->task->stack_start;
> > +
> > +					if (vma->vm_start <= stack_start && 
> > +					    vma->vm_end >= stack_start)
> > +						name="[thread stack]";
> > +#endif
> 
> This too should be unconditional IMO (it's useful, and 
> ultra-embedded systems worried about kernel .text size can turn off 
> CONFIG_PROC_FS anyway), _and_ i think we could do even better.
> 

The CONFIG_PROC_STACK thing was only for test. I prefer it as an "always
on" feature.

> How about extending /proc/X/maps with:
> 
>  b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
>  b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
>  bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack, usage: 1391 kB]
> 
> This is deterministically parseable, and meaningful-at-a-glance. 
> Similarly for 'thread stack'.
> 

Good idea. Should i write a new patch for this or will be this your job?

> This way we dont need any new files in /proc - that just increases 
> the per task memory overhead.
> 
> What do you think?
> 
> 	Ingo


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch [1/3]
@ 2009-04-02 21:26     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-04-02 21:26 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Andrew Morton, linux-kernel, linux-mm, Peter Zijlstra,
	Joerg Engel, Thomas Gleixner

Am Mittwoch, den 01.04.2009, 21:31 +0200 schrieb Ingo Molnar:
> * Stefani Seibold <stefani@seibold.net> wrote:
> 
> > diff -u -N -r linux-2.6.29.orig/fs/exec.c linux-2.6.29/fs/exec.c
> > --- linux-2.6.29.orig/fs/exec.c	2009-03-24 00:12:14.000000000 +0100
> > +++ linux-2.6.29/fs/exec.c	2009-03-31 16:02:55.000000000 +0200
> > @@ -1336,6 +1336,10 @@
> >  	if (retval < 0)
> >  		goto out;
> >  
> > +#ifdef CONFIG_PROC_STACK
> > +	current->stack_start = current->mm->start_stack;
> > +#endif
> 
> Ok. The 1/3 patch, the whole "display where the stack is" thing is 
> obviously useful and we know that.
> 
> Today we display this:
> 
>  earth4:~/tip> cat /proc/self/maps 
>  00110000-00111000 r-xp 00110000 00:00 0          [vdso]
>  0053e000-0055e000 r-xp 00000000 09:00 54591597   /lib/ld-2.9.so
>  .
>  .
>  .
>  bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack]
> 
> I was the one who added the [stack], [heap] and [vdso] annotations a 
> few years ago and user-space developers liked it very much.
> 
> Tools parsing these files wont break [they dont care about the final 
> column] - so there's no ABI worries and we can certainly do more 
> here and enhance it.
> 
> You extend the above output with (in essence):
> 
> > +#ifdef CONFIG_PROC_STACK
> > +static inline void task_show_stack_usage(struct seq_file *m,
> > +						struct task_struct *p)
> 
> It would be better to put this into a fresh, related feature that 
> went upstream recently:
> 
>  spirit:~> cat /proc/self/stack
>  [<ffffffff8101c333>] save_stack_trace_tsk+0x26/0x43
>  .
>  .
>  .
> That displays the kernel stack data - and we could display 
> information about the user-stack data as well.
> 

/proc/self/stack is a good place for a more detailed information,
like the start address of the stack, the current usage and the highest
used address.

> This #ifdef:
> 
> > +#ifdef CONFIG_STACK_GROWSUP
> > +	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
> > +#else
> > +	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
> > +#endif
> 
> Should be hidden in a task_user_stack() inline helper.
> 

Yes, this is more readable.

> Another thing is:
> 
> > @@ -240,6 +240,18 @@
> >  				} else if (vma->vm_start <= mm->start_stack &&
> >  					   vma->vm_end >= mm->start_stack) {
> >  					name = "[stack]";
> > +#ifdef CONFIG_PROC_STACK
> > +				} else {
> > +					unsigned long stack_start;
> > +
> > +					stack_start =
> > +						((struct proc_maps_private *)
> > +						 m->private)->task->stack_start;
> > +
> > +					if (vma->vm_start <= stack_start && 
> > +					    vma->vm_end >= stack_start)
> > +						name="[thread stack]";
> > +#endif
> 
> This too should be unconditional IMO (it's useful, and 
> ultra-embedded systems worried about kernel .text size can turn off 
> CONFIG_PROC_FS anyway), _and_ i think we could do even better.
> 

The CONFIG_PROC_STACK thing was only for test. I prefer it as an "always
on" feature.

> How about extending /proc/X/maps with:
> 
>  b7db9000-b7fb9000 r--p 00000000 09:00 50364418   /usr/lib/locale/locale-archive
>  b7fb9000-b7fbb000 rw-p b7fb9000 00:00 0 
>  bffc7000-bffdc000 rw-p bffeb000 00:00 0          [stack, usage: 1391 kB]
> 
> This is deterministically parseable, and meaningful-at-a-glance. 
> Similarly for 'thread stack'.
> 

Good idea. Should i write a new patch for this or will be this your job?

> This way we dont need any new files in /proc - that just increases 
> the per task memory overhead.
> 
> What do you think?
> 
> 	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Detailed Stack Information Patch Next Generation
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-03 20:34     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-03 20:34 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Ingo Molnar, Andrew Morton, Joerg Engel, Thomas Gleixner

Hi everybody,

kernel 2.6.30 is near so i think it is time for the next try.

This is the new version of the "detailed stack info" patch which give
you a better overview of the userland application stack usage,
especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Redesigned everything what was suggested by Ingo
 - the thread watch monitor is gone
 - the /proc/stackmon entry is also gone
 - slime done

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

I think it is now ready for inclusion in the main kernel. Ingo what do
you think?

Greetings,
Stefani

 fs/exec.c             |    2 +
 fs/proc/array.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 ++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    3 ++
 5 files changed, 88 insertions(+), 1 deletion(-)

-patch begins here--------------------------------------------------------------

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-03 17:30:47.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-03 17:32:53.000000000 +0200
@@ -82,6 +82,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
+#include <linux/pfn.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -321,6 +322,71 @@
 			p->nivcsw);
 }
 
+#ifdef CONFIG_STACK_GROWSUP
+static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stack_usage;
+	unsigned long	esp;
+
+	esp = KSTK_ESP(p);
+
+	stack_usage = (PFN_ALIGN(esp)-PFN_ALIGN(p->stack_start));
+
+	for (i = vma->vm_end; i-PAGE_SIZE > esp; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if ((!IS_ERR(page) == 0) || (page))
+			break;
+	}
+	return ((i - esp + stack_usage) >> (PAGE_SHIFT)) + 1;
+}
+#else
+static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stack_usage;
+	unsigned long	esp;
+
+	esp = KSTK_ESP(p);
+
+	stack_usage = (PFN_ALIGN(p->stack_start) - PFN_ALIGN(esp));
+
+	for (i = vma->vm_start; i+PAGE_SIZE <= esp; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if ((!IS_ERR(page) == 0) || (page))
+			break;
+	}
+	return ((esp - i + stack_usage) >> (PAGE_SHIFT)) + 1;
+}
+#endif
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_pages(vma, p) << (PAGE_SHIFT - 10));
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +406,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +548,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-03 17:30:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-03 17:30:47.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-03 17:36:42.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-03 17:30:47.000000000 +0200
@@ -1092,6 +1092,9 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = (stack_start == KSTK_ESP(current)) ?
+		current->stack_start : stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Detailed Stack Information Patch Next Generation
@ 2009-06-03 20:34     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-03 20:34 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Ingo Molnar, Andrew Morton, Joerg Engel, Thomas Gleixner

Hi everybody,

kernel 2.6.30 is near so i think it is time for the next try.

This is the new version of the "detailed stack info" patch which give
you a better overview of the userland application stack usage,
especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Redesigned everything what was suggested by Ingo
 - the thread watch monitor is gone
 - the /proc/stackmon entry is also gone
 - slime done

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

I think it is now ready for inclusion in the main kernel. Ingo what do
you think?

Greetings,
Stefani

 fs/exec.c             |    2 +
 fs/proc/array.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 ++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    3 ++
 5 files changed, 88 insertions(+), 1 deletion(-)

-patch begins here--------------------------------------------------------------

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-03 17:30:47.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-03 17:32:53.000000000 +0200
@@ -82,6 +82,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
+#include <linux/pfn.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -321,6 +322,71 @@
 			p->nivcsw);
 }
 
+#ifdef CONFIG_STACK_GROWSUP
+static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stack_usage;
+	unsigned long	esp;
+
+	esp = KSTK_ESP(p);
+
+	stack_usage = (PFN_ALIGN(esp)-PFN_ALIGN(p->stack_start));
+
+	for (i = vma->vm_end; i-PAGE_SIZE > esp; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if ((!IS_ERR(page) == 0) || (page))
+			break;
+	}
+	return ((i - esp + stack_usage) >> (PAGE_SHIFT)) + 1;
+}
+#else
+static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stack_usage;
+	unsigned long	esp;
+
+	esp = KSTK_ESP(p);
+
+	stack_usage = (PFN_ALIGN(p->stack_start) - PFN_ALIGN(esp));
+
+	for (i = vma->vm_start; i+PAGE_SIZE <= esp; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if ((!IS_ERR(page) == 0) || (page))
+			break;
+	}
+	return ((esp - i + stack_usage) >> (PAGE_SHIFT)) + 1;
+}
+#endif
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_pages(vma, p) << (PAGE_SHIFT - 10));
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +406,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +548,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-03 17:30:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-03 17:36:41.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-03 17:30:47.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-03 17:36:42.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-03 17:30:47.000000000 +0200
@@ -1092,6 +1092,9 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = (stack_start == KSTK_ESP(current)) ?
+		current->stack_start : stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch Next Generation
  2009-06-03 20:34     ` Stefani Seibold
@ 2009-06-03 21:06       ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-03 21:06 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, mingo, joern, tglx


> Subject: Detailed Stack Information Patch Next Generation

That's not a very useful patch title.  Something like

	[patch] procfs: provide stack information for threads

would suit.

On Wed, 03 Jun 2009 22:34:09 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> Hi everybody,
> 
> kernel 2.6.30 is near so i think it is time for the next try.
> 
> This is the new version of the "detailed stack info" patch which give
> you a better overview of the userland application stack usage,
> especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Redesigned everything what was suggested by Ingo
>  - the thread watch monitor is gone
>  - the /proc/stackmon entry is also gone
>  - slime done
> 
> The patch is against 2.6.30-rc7 and tested with on intel and ppc
> architectures.
> 
> I think it is now ready for inclusion in the main kernel. Ingo what do
> you think?
> 

Missing Signed-off-by:

> 
>  fs/exec.c             |    2 +
>  fs/proc/array.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  fs/proc/task_mmu.c    |   14 ++++++++++
>  include/linux/sched.h |    1 
>  kernel/fork.c         |    3 ++
>  5 files changed, 88 insertions(+), 1 deletion(-)
> 
> -patch begins here--------------------------------------------------------------
> 
> diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
> --- linux-2.6.30.orig/fs/exec.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/exec.c	2009-06-03 17:30:47.000000000 +0200
> @@ -1328,6 +1328,8 @@
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
> --- linux-2.6.30.orig/fs/proc/array.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/proc/array.c	2009-06-03 17:32:53.000000000 +0200
> @@ -82,6 +82,7 @@
>  #include <linux/pid_namespace.h>
>  #include <linux/ptrace.h>
>  #include <linux/tracehook.h>
> +#include <linux/pfn.h>
>  
>  #include <asm/pgtable.h>
>  #include <asm/processor.h>
> @@ -321,6 +322,71 @@
>  			p->nivcsw);
>  }
>  
> +#ifdef CONFIG_STACK_GROWSUP
> +static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stack_usage;
> +	unsigned long	esp;

It's unclear what the units are here.  Are they in bytes?  Pages?  Code
comments and well-chosen identifiers are the way to fix this.

> +	esp = KSTK_ESP(p);

So `esp' is in bytes.

> +	stack_usage = (PFN_ALIGN(esp)-PFN_ALIGN(p->stack_start));

And `stack_usage' measures bytes

> +	for (i = vma->vm_end; i-PAGE_SIZE > esp; i -= PAGE_SIZE) {

And `i' measures bytes

> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if ((!IS_ERR(page) == 0) || (page))

Why not simply

		if (IS_ERR(page) || page)

?

And shouldn't it be !page?

> +			break;
> +	}
> +	return ((i - esp + stack_usage) >> (PAGE_SHIFT)) + 1;

And we return a number-of-pages.  Fair enough.

> +}
> +#else
> +static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stack_usage;
> +	unsigned long	esp;
> +
> +	esp = KSTK_ESP(p);
> +
> +	stack_usage = (PFN_ALIGN(p->stack_start) - PFN_ALIGN(esp));
> +
> +	for (i = vma->vm_start; i+PAGE_SIZE <= esp; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if ((!IS_ERR(page) == 0) || (page))
> +			break;
> +	}
> +	return ((esp - i + stack_usage) >> (PAGE_SHIFT)) + 1;
> +}

Dittoes.

> +#endif
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_pages(vma, p) << (PAGE_SHIFT - 10));

So get_stack_pages() did a bytes-to-pages conversion then its sole
caller does a pages-to-bytes conversion.  Can this be simplified?

> +
> +		mmput(mm);
> +	}
> +}
>
>  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
>  			struct pid *pid, struct task_struct *task)
>  {
> @@ -340,6 +406,7 @@
>  	task_show_regs(m, task);
>  #endif
>  	task_context_switch_counts(m, task);
> +	task_show_stack_usage(m, task);
>  	return 0;
>  }
>  
> @@ -481,7 +548,7 @@
>  		rsslim,
>  		mm ? mm->start_code : 0,
>  		mm ? mm->end_code : 0,
> -		(permitted && mm) ? mm->start_stack : 0,
> +		(permitted) ? task->stack_start : 0,
>  		esp,
>  		eip,
>  		/* The signal information here is obsolete.
> diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
> --- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-03 17:30:47.000000000 +0200
> @@ -242,6 +242,20 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						m->private)->task->stack_start;

Like this:

					unsiged long stack_start;
					struct proc_maps_private *pmp;

					pmp = m->private;
					stack_start = pmp->task->stack_start;

> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}
>  				}
>  			} else {
>  				name = "[vdso]";
> diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-03 17:30:47.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  
>  /* Future-safe accessor for struct task_struct's cpus_allowed. */
> diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
> --- linux-2.6.30.orig/kernel/fork.c	2009-06-03 17:36:42.000000000 +0200
> +++ linux-2.6.30/kernel/fork.c	2009-06-03 17:30:47.000000000 +0200
> @@ -1092,6 +1092,9 @@
>  	if (unlikely(current->ptrace))
>  		ptrace_fork(p, clone_flags);
>  
> +	p->stack_start = (stack_start == KSTK_ESP(current)) ?
> +		current->stack_start : stack_start;
> +

hm.  What's this doing?

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Detailed Stack Information Patch Next Generation
@ 2009-06-03 21:06       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-03 21:06 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, mingo, joern, tglx


> Subject: Detailed Stack Information Patch Next Generation

That's not a very useful patch title.  Something like

	[patch] procfs: provide stack information for threads

would suit.

On Wed, 03 Jun 2009 22:34:09 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> Hi everybody,
> 
> kernel 2.6.30 is near so i think it is time for the next try.
> 
> This is the new version of the "detailed stack info" patch which give
> you a better overview of the userland application stack usage,
> especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Redesigned everything what was suggested by Ingo
>  - the thread watch monitor is gone
>  - the /proc/stackmon entry is also gone
>  - slime done
> 
> The patch is against 2.6.30-rc7 and tested with on intel and ppc
> architectures.
> 
> I think it is now ready for inclusion in the main kernel. Ingo what do
> you think?
> 

Missing Signed-off-by:

> 
>  fs/exec.c             |    2 +
>  fs/proc/array.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  fs/proc/task_mmu.c    |   14 ++++++++++
>  include/linux/sched.h |    1 
>  kernel/fork.c         |    3 ++
>  5 files changed, 88 insertions(+), 1 deletion(-)
> 
> -patch begins here--------------------------------------------------------------
> 
> diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
> --- linux-2.6.30.orig/fs/exec.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/exec.c	2009-06-03 17:30:47.000000000 +0200
> @@ -1328,6 +1328,8 @@
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
> --- linux-2.6.30.orig/fs/proc/array.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/proc/array.c	2009-06-03 17:32:53.000000000 +0200
> @@ -82,6 +82,7 @@
>  #include <linux/pid_namespace.h>
>  #include <linux/ptrace.h>
>  #include <linux/tracehook.h>
> +#include <linux/pfn.h>
>  
>  #include <asm/pgtable.h>
>  #include <asm/processor.h>
> @@ -321,6 +322,71 @@
>  			p->nivcsw);
>  }
>  
> +#ifdef CONFIG_STACK_GROWSUP
> +static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stack_usage;
> +	unsigned long	esp;

It's unclear what the units are here.  Are they in bytes?  Pages?  Code
comments and well-chosen identifiers are the way to fix this.

> +	esp = KSTK_ESP(p);

So `esp' is in bytes.

> +	stack_usage = (PFN_ALIGN(esp)-PFN_ALIGN(p->stack_start));

And `stack_usage' measures bytes

> +	for (i = vma->vm_end; i-PAGE_SIZE > esp; i -= PAGE_SIZE) {

And `i' measures bytes

> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if ((!IS_ERR(page) == 0) || (page))

Why not simply

		if (IS_ERR(page) || page)

?

And shouldn't it be !page?

> +			break;
> +	}
> +	return ((i - esp + stack_usage) >> (PAGE_SHIFT)) + 1;

And we return a number-of-pages.  Fair enough.

> +}
> +#else
> +static inline unsigned long get_stack_pages(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stack_usage;
> +	unsigned long	esp;
> +
> +	esp = KSTK_ESP(p);
> +
> +	stack_usage = (PFN_ALIGN(p->stack_start) - PFN_ALIGN(esp));
> +
> +	for (i = vma->vm_start; i+PAGE_SIZE <= esp; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if ((!IS_ERR(page) == 0) || (page))
> +			break;
> +	}
> +	return ((esp - i + stack_usage) >> (PAGE_SHIFT)) + 1;
> +}

Dittoes.

> +#endif
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_pages(vma, p) << (PAGE_SHIFT - 10));

So get_stack_pages() did a bytes-to-pages conversion then its sole
caller does a pages-to-bytes conversion.  Can this be simplified?

> +
> +		mmput(mm);
> +	}
> +}
>
>  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
>  			struct pid *pid, struct task_struct *task)
>  {
> @@ -340,6 +406,7 @@
>  	task_show_regs(m, task);
>  #endif
>  	task_context_switch_counts(m, task);
> +	task_show_stack_usage(m, task);
>  	return 0;
>  }
>  
> @@ -481,7 +548,7 @@
>  		rsslim,
>  		mm ? mm->start_code : 0,
>  		mm ? mm->end_code : 0,
> -		(permitted && mm) ? mm->start_stack : 0,
> +		(permitted) ? task->stack_start : 0,
>  		esp,
>  		eip,
>  		/* The signal information here is obsolete.
> diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
> --- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-03 17:30:47.000000000 +0200
> @@ -242,6 +242,20 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						m->private)->task->stack_start;

Like this:

					unsiged long stack_start;
					struct proc_maps_private *pmp;

					pmp = m->private;
					stack_start = pmp->task->stack_start;

> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}
>  				}
>  			} else {
>  				name = "[vdso]";
> diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-03 17:36:41.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-03 17:30:47.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  
>  /* Future-safe accessor for struct task_struct's cpus_allowed. */
> diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
> --- linux-2.6.30.orig/kernel/fork.c	2009-06-03 17:36:42.000000000 +0200
> +++ linux-2.6.30/kernel/fork.c	2009-06-03 17:30:47.000000000 +0200
> @@ -1092,6 +1092,9 @@
>  	if (unlikely(current->ptrace))
>  		ptrace_fork(p, clone_flags);
>  
> +	p->stack_start = (stack_start == KSTK_ESP(current)) ?
> +		current->stack_start : stack_start;
> +

hm.  What's this doing?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-04 11:23     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 11:23 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Ingo Molnar, Andrew Morton, Joerg Engel, Thomas Gleixner

Hi everybody,

This is the latest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Redesigned everything what was suggested by Andrew
 - slime done

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

Greetings,
Stefani

 fs/exec.c             |    2 +
 fs/proc/array.c       |   52 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 70 insertions(+), 1 deletion(-)

-patch begins here--------------------------------------------------------------

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-04 10:37:53.000000000 +0200
@@ -321,6 +321,55 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, p) >> 10);
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +389,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +531,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 09:32:35.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);

Signed-off-by: Stefani Seibold <stefani@seibold.net>



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads
@ 2009-06-04 11:23     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 11:23 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Ingo Molnar, Andrew Morton, Joerg Engel, Thomas Gleixner

Hi everybody,

This is the latest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Redesigned everything what was suggested by Andrew
 - slime done

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

Greetings,
Stefani

 fs/exec.c             |    2 +
 fs/proc/array.c       |   52 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 70 insertions(+), 1 deletion(-)

-patch begins here--------------------------------------------------------------

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-04 10:37:53.000000000 +0200
@@ -321,6 +321,55 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, p) >> 10);
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +389,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +531,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 09:32:35.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+
+					stack_start =
+						((struct proc_maps_private *)
+						m->private)->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);

Signed-off-by: Stefani Seibold <stefani@seibold.net>


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 11:23     ` Stefani Seibold
@ 2009-06-04 11:37       ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 11:37 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner

On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:

> Hi everybody,
> 
> This is the latest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Redesigned everything what was suggested by Andrew

You didn't account for some of my comments.  I'll repeat the ones which
I recall below.

>  - slime done

What's "slime"?

> +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stkpage;
> +
> +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> +
> +#ifdef CONFIG_STACK_GROWSUP
> +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> +
> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if (!IS_ERR(page) && page)

Shouldn't this be !page?

> +			break;
> +	}
> +	return i - (p->stack_start & PAGE_MASK);
> +#else
> +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if (!IS_ERR(page) && page)

Ditto

> +			break;
> +	}
> +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> +#endif
> +}
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_usage_in_bytes(vma, p) >> 10);
> +
> +		mmput(mm);
> +	}
> +}
> +
>  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
>  			struct pid *pid, struct task_struct *task)
>  {
> @@ -340,6 +389,7 @@
>  	task_show_regs(m, task);
>  #endif
>  	task_context_switch_counts(m, task);
> +	task_show_stack_usage(m, task);
>  	return 0;
>  }
>  
> @@ -481,7 +531,7 @@
>  		rsslim,
>  		mm ? mm->start_code : 0,
>  		mm ? mm->end_code : 0,
> -		(permitted && mm) ? mm->start_stack : 0,
> +		(permitted) ? task->stack_start : 0,
>  		esp,
>  		eip,
>  		/* The signal information here is obsolete.
> diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
> --- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 09:32:35.000000000 +0200
> @@ -242,6 +242,20 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						m->private)->task->stack_start;

I'd suggested a clearer/cleaner way of implementing this.

> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}
>  				}
>  			} else {
>  				name = "[vdso]";
> diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  
>  /* Future-safe accessor for struct task_struct's cpus_allowed. */
> diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
> --- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
> @@ -1092,6 +1092,8 @@
>  	if (unlikely(current->ptrace))
>  		ptrace_fork(p, clone_flags);
>  
> +	p->stack_start = stack_start;

OK, that got simpler.

> Signed-off-by: Stefani Seibold <stefani@seibold.net>

This should be positioned at the end of the changelog, ahead of the
patch itself.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-04 11:37       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 11:37 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner

On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:

> Hi everybody,
> 
> This is the latest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Redesigned everything what was suggested by Andrew

You didn't account for some of my comments.  I'll repeat the ones which
I recall below.

>  - slime done

What's "slime"?

> +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stkpage;
> +
> +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> +
> +#ifdef CONFIG_STACK_GROWSUP
> +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> +
> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if (!IS_ERR(page) && page)

Shouldn't this be !page?

> +			break;
> +	}
> +	return i - (p->stack_start & PAGE_MASK);
> +#else
> +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if (!IS_ERR(page) && page)

Ditto

> +			break;
> +	}
> +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> +#endif
> +}
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_usage_in_bytes(vma, p) >> 10);
> +
> +		mmput(mm);
> +	}
> +}
> +
>  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
>  			struct pid *pid, struct task_struct *task)
>  {
> @@ -340,6 +389,7 @@
>  	task_show_regs(m, task);
>  #endif
>  	task_context_switch_counts(m, task);
> +	task_show_stack_usage(m, task);
>  	return 0;
>  }
>  
> @@ -481,7 +531,7 @@
>  		rsslim,
>  		mm ? mm->start_code : 0,
>  		mm ? mm->end_code : 0,
> -		(permitted && mm) ? mm->start_stack : 0,
> +		(permitted) ? task->stack_start : 0,
>  		esp,
>  		eip,
>  		/* The signal information here is obsolete.
> diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
> --- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 09:32:35.000000000 +0200
> @@ -242,6 +242,20 @@
>  				} else if (vma->vm_start <= mm->start_stack &&
>  					   vma->vm_end >= mm->start_stack) {
>  					name = "[stack]";
> +				} else {
> +					unsigned long stack_start;
> +
> +					stack_start =
> +						((struct proc_maps_private *)
> +						m->private)->task->stack_start;

I'd suggested a clearer/cleaner way of implementing this.

> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}
>  				}
>  			} else {
>  				name = "[vdso]";
> diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  
>  /* Future-safe accessor for struct task_struct's cpus_allowed. */
> diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
> --- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
> @@ -1092,6 +1092,8 @@
>  	if (unlikely(current->ptrace))
>  		ptrace_fork(p, clone_flags);
>  
> +	p->stack_start = stack_start;

OK, that got simpler.

> Signed-off-by: Stefani Seibold <stefani@seibold.net>

This should be positioned at the end of the changelog, ahead of the
patch itself.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 11:37       ` Andrew Morton
@ 2009-06-04 11:56         ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 11:56 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner


Am Donnerstag, den 04.06.2009, 04:37 -0700 schrieb Andrew Morton:
> On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:
> >  - slime done
> 
> What's "slime"?
> 

Sorry, that was a typo, should be "slim down".

> > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> 
> Shouldn't this be !page?
> 

No, this is correct... I walk through the top of vma to the first mapped
page, this is the high water mark of the stack.

> > +					unsigned long stack_start;
> > +
> > +					stack_start =
> > +						((struct proc_maps_private *)
> > +						m->private)->task->stack_start;
> 
> I'd suggested a clearer/cleaner way of implementing this.
> 

Sorry, i can not see a problem here. In your last posting you wrote
thats okay! And i have no idea how to make this expression
clearer/cleaner.

> > Signed-off-by: Stefani Seibold <stefani@seibold.net>
> 
> This should be positioned at the end of the changelog, ahead of the
> patch itself.
> 

Next time i will do this, okay?



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-04 11:56         ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 11:56 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner


Am Donnerstag, den 04.06.2009, 04:37 -0700 schrieb Andrew Morton:
> On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:
> >  - slime done
> 
> What's "slime"?
> 

Sorry, that was a typo, should be "slim down".

> > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> 
> Shouldn't this be !page?
> 

No, this is correct... I walk through the top of vma to the first mapped
page, this is the high water mark of the stack.

> > +					unsigned long stack_start;
> > +
> > +					stack_start =
> > +						((struct proc_maps_private *)
> > +						m->private)->task->stack_start;
> 
> I'd suggested a clearer/cleaner way of implementing this.
> 

Sorry, i can not see a problem here. In your last posting you wrote
thats okay! And i have no idea how to make this expression
clearer/cleaner.

> > Signed-off-by: Stefani Seibold <stefani@seibold.net>
> 
> This should be positioned at the end of the changelog, ahead of the
> patch itself.
> 

Next time i will do this, okay?


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 11:56         ` Stefani Seibold
@ 2009-06-04 17:57           ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 17:57 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner

On Thu, 04 Jun 2009 13:56:29 +0200 Stefani Seibold <stefani@seibold.net> wrote:

> 
> Am Donnerstag, den 04.06.2009, 04:37 -0700 schrieb Andrew Morton:
> > On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:
> > >  - slime done
> > 
> > What's "slime"?
> > 
> 
> Sorry, that was a typo, should be "slim down".

heh, OK.  Good typo.

> > > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > > +
> > > +		page = follow_page(vma, i, 0);
> > > +
> > > +		if (!IS_ERR(page) && page)
> > 
> > Shouldn't this be !page?
> > 
> 
> No, this is correct... I walk through the top of vma to the first mapped
> page, this is the high water mark of the stack.

Ah, duh, OK.

> > > +					unsigned long stack_start;
> > > +
> > > +					stack_start =
> > > +						((struct proc_maps_private *)
> > > +						m->private)->task->stack_start;
> > 
> > I'd suggested a clearer/cleaner way of implementing this.
> > 
> 
> Sorry, i can not see a problem here. In your last posting you wrote
> thats okay! And i have no idea how to make this expression
> clearer/cleaner.

Add a new intermediate variable:
					unsigned long stack_start;
					struct proc_maps_private *pmp;

					pmp = m->private;
					stack_start = pmp->task->stack_start;



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-04 17:57           ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 17:57 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, linux-mm, Ingo Molnar, Joerg Engel, Thomas Gleixner

On Thu, 04 Jun 2009 13:56:29 +0200 Stefani Seibold <stefani@seibold.net> wrote:

> 
> Am Donnerstag, den 04.06.2009, 04:37 -0700 schrieb Andrew Morton:
> > On Thu, 04 Jun 2009 13:23:48 +0200 Stefani Seibold <stefani@seibold.net> wrote:
> > >  - slime done
> > 
> > What's "slime"?
> > 
> 
> Sorry, that was a typo, should be "slim down".

heh, OK.  Good typo.

> > > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > > +
> > > +		page = follow_page(vma, i, 0);
> > > +
> > > +		if (!IS_ERR(page) && page)
> > 
> > Shouldn't this be !page?
> > 
> 
> No, this is correct... I walk through the top of vma to the first mapped
> page, this is the high water mark of the stack.

Ah, duh, OK.

> > > +					unsigned long stack_start;
> > > +
> > > +					stack_start =
> > > +						((struct proc_maps_private *)
> > > +						m->private)->task->stack_start;
> > 
> > I'd suggested a clearer/cleaner way of implementing this.
> > 
> 
> Sorry, i can not see a problem here. In your last posting you wrote
> thats okay! And i have no idea how to make this expression
> clearer/cleaner.

Add a new intermediate variable:
					unsigned long stack_start;
					struct proc_maps_private *pmp;

					pmp = m->private;
					stack_start = pmp->task->stack_start;


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-04 20:21     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 20:21 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Code cleanup suggested by Andrew

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


 fs/exec.c             |    2 +
 fs/proc/array.c       |   52 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 70 insertions(+), 1 deletion(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-04 10:37:53.000000000 +0200
@@ -321,6 +321,55 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, p) >> 10);
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +389,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +531,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads
@ 2009-06-04 20:21     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-04 20:21 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack.

Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

I also fixed stack base address in /proc/<pid>/task/*/stat to the base
address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Code cleanup suggested by Andrew

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


 fs/exec.c             |    2 +
 fs/proc/array.c       |   52 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 70 insertions(+), 1 deletion(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-04 10:37:53.000000000 +0200
@@ -321,6 +321,55 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm;
+
+	mm = get_task_mm(p);
+
+	if (mm) {
+		vma = find_vma(mm, p->stack_start);
+
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, p) >> 10);
+
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +389,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +531,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 20:21     ` Stefani Seibold
@ 2009-06-04 21:23       ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 21:23 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Thu, 04 Jun 2009 22:21:13 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Code cleanup suggested by Andrew
> 
> The patch is against 2.6.30-rc7 and tested with on intel and ppc
> architectures.

OK, we're getting there.

> +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stkpage;
> +
> +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> +
> +#ifdef CONFIG_STACK_GROWSUP
> +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> +
> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if (!IS_ERR(page) && page)
> +			break;
> +	}
> +	return i - (p->stack_start & PAGE_MASK);
> +#else
> +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if (!IS_ERR(page) && page)
> +			break;
> +	}
> +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> +#endif
> +}
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_usage_in_bytes(vma, p) >> 10);
> +
> +		mmput(mm);
> +	}
> +}

Both follow_page() and find_vma() require locking: down_read(mmap_sem)
or down_write(mmap_sem).  down_read() is appropriate here.

> +				} else {
> +					unsigned long stack_start;
> +					struct proc_maps_private *pmp;
> +
> +					pmp = m->private;
> +					stack_start = pmp->task->stack_start;
> +
> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}

You're making changes to the user interface but it's not terribly clear
what they look like.  Please include sample output from the affected
procfs files so that we can review the proposed changes.

Please update the userspace documentation to reflect the changes. 
Documentation/filesystems/proc.txt documents VmStk, so probably that is
the appropriate place.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-04 21:23       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-04 21:23 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Thu, 04 Jun 2009 22:21:13 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
> 
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
> Changes since last posting:
> 
>  - Code cleanup suggested by Andrew
> 
> The patch is against 2.6.30-rc7 and tested with on intel and ppc
> architectures.

OK, we're getting there.

> +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> +					struct task_struct *p)
> +{
> +	unsigned long	i;
> +	struct page	*page;
> +	unsigned long	stkpage;
> +
> +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> +
> +#ifdef CONFIG_STACK_GROWSUP
> +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> +
> +		page = follow_page(vma, i-PAGE_SIZE, 0);
> +
> +		if (!IS_ERR(page) && page)
> +			break;
> +	}
> +	return i - (p->stack_start & PAGE_MASK);
> +#else
> +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> +
> +		page = follow_page(vma, i, 0);
> +
> +		if (!IS_ERR(page) && page)
> +			break;
> +	}
> +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> +#endif
> +}
> +
> +static inline void task_show_stack_usage(struct seq_file *m,
> +						struct task_struct *p)
> +{
> +	struct vm_area_struct	*vma;
> +	struct mm_struct	*mm;
> +
> +	mm = get_task_mm(p);
> +
> +	if (mm) {
> +		vma = find_vma(mm, p->stack_start);
> +
> +		if (vma)
> +			seq_printf(m, "Stack usage:\t%lu kB\n",
> +				get_stack_usage_in_bytes(vma, p) >> 10);
> +
> +		mmput(mm);
> +	}
> +}

Both follow_page() and find_vma() require locking: down_read(mmap_sem)
or down_write(mmap_sem).  down_read() is appropriate here.

> +				} else {
> +					unsigned long stack_start;
> +					struct proc_maps_private *pmp;
> +
> +					pmp = m->private;
> +					stack_start = pmp->task->stack_start;
> +
> +					if (vma->vm_start <= stack_start &&
> +					    vma->vm_end >= stack_start) {
> +						pad_len_spaces(m, len);
> +						seq_printf(m,
> +						 "[thread stack: %08lx]",
> +						 stack_start);
> +					}

You're making changes to the user interface but it's not terribly clear
what they look like.  Please include sample output from the affected
procfs files so that we can review the proposed changes.

Please update the userspace documentation to reflect the changes. 
Documentation/filesystems/proc.txt documents VmStk, so probably that is
the appropriate place.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 21:23       ` Andrew Morton
@ 2009-06-05 19:12         ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-05 19:12 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm


> > +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> > +					struct task_struct *p)
> > +{
> > +	unsigned long	i;
> > +	struct page	*page;
> > +	unsigned long	stkpage;
> > +
> > +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> > +
> > +#ifdef CONFIG_STACK_GROWSUP
> > +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i-PAGE_SIZE, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> > +			break;
> > +	}
> > +	return i - (p->stack_start & PAGE_MASK);
> > +#else
> > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> > +			break;
> > +	}
> > +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> > +#endif
> > +}
> > +
> > +static inline void task_show_stack_usage(struct seq_file *m,
> > +						struct task_struct *p)
> > +{
> > +	struct vm_area_struct	*vma;
> > +	struct mm_struct	*mm;
> > +
> > +	mm = get_task_mm(p);
> > +
> > +	if (mm) {
> > +		vma = find_vma(mm, p->stack_start);
> > +
> > +		if (vma)
> > +			seq_printf(m, "Stack usage:\t%lu kB\n",
> > +				get_stack_usage_in_bytes(vma, p) >> 10);
> > +
> > +		mmput(mm);
> > +	}
> > +}
> 
> Both follow_page() and find_vma() require locking: down_read(mmap_sem)
> or down_write(mmap_sem).  down_read() is appropriate here.
> 

Didn't know that this require a lock, but i will fix this.

> > +				} else {
> > +					unsigned long stack_start;
> > +					struct proc_maps_private *pmp;
> > +
> > +					pmp = m->private;
> > +					stack_start = pmp->task->stack_start;
> > +
> > +					if (vma->vm_start <= stack_start &&
> > +					    vma->vm_end >= stack_start) {
> > +						pad_len_spaces(m, len);
> > +						seq_printf(m,
> > +						 "[thread stack: %08lx]",
> > +						 stack_start);
> > +					}
> 
> You're making changes to the user interface but it's not terribly clear
> what they look like.  Please include sample output from the affected
> procfs files so that we can review the proposed changes.
> 

This change to the user interface was suggest by ingo molnar. I will add
the sample output in the next version.

> Please update the userspace documentation to reflect the changes. 
> Documentation/filesystems/proc.txt documents VmStk, so probably that is
> the appropriate place.
> 

Good idea, but the proc.txt documentation about /proc/<pid>/status (line
140) and the contents of the /proc/<pid>/stat file (line 192) is
complete outdated. And there is also no documentation
about /proc/<pid>/*maps. 

So i want to try to fix the missing documentation in proc.txt in a
separate patch. Will this okay by you?

Greetings



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-05 19:12         ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-05 19:12 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm


> > +static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
> > +					struct task_struct *p)
> > +{
> > +	unsigned long	i;
> > +	struct page	*page;
> > +	unsigned long	stkpage;
> > +
> > +	stkpage = KSTK_ESP(p) & PAGE_MASK;
> > +
> > +#ifdef CONFIG_STACK_GROWSUP
> > +	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i-PAGE_SIZE, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> > +			break;
> > +	}
> > +	return i - (p->stack_start & PAGE_MASK);
> > +#else
> > +	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
> > +
> > +		page = follow_page(vma, i, 0);
> > +
> > +		if (!IS_ERR(page) && page)
> > +			break;
> > +	}
> > +	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
> > +#endif
> > +}
> > +
> > +static inline void task_show_stack_usage(struct seq_file *m,
> > +						struct task_struct *p)
> > +{
> > +	struct vm_area_struct	*vma;
> > +	struct mm_struct	*mm;
> > +
> > +	mm = get_task_mm(p);
> > +
> > +	if (mm) {
> > +		vma = find_vma(mm, p->stack_start);
> > +
> > +		if (vma)
> > +			seq_printf(m, "Stack usage:\t%lu kB\n",
> > +				get_stack_usage_in_bytes(vma, p) >> 10);
> > +
> > +		mmput(mm);
> > +	}
> > +}
> 
> Both follow_page() and find_vma() require locking: down_read(mmap_sem)
> or down_write(mmap_sem).  down_read() is appropriate here.
> 

Didn't know that this require a lock, but i will fix this.

> > +				} else {
> > +					unsigned long stack_start;
> > +					struct proc_maps_private *pmp;
> > +
> > +					pmp = m->private;
> > +					stack_start = pmp->task->stack_start;
> > +
> > +					if (vma->vm_start <= stack_start &&
> > +					    vma->vm_end >= stack_start) {
> > +						pad_len_spaces(m, len);
> > +						seq_printf(m,
> > +						 "[thread stack: %08lx]",
> > +						 stack_start);
> > +					}
> 
> You're making changes to the user interface but it's not terribly clear
> what they look like.  Please include sample output from the affected
> procfs files so that we can review the proposed changes.
> 

This change to the user interface was suggest by ingo molnar. I will add
the sample output in the next version.

> Please update the userspace documentation to reflect the changes. 
> Documentation/filesystems/proc.txt documents VmStk, so probably that is
> the appropriate place.
> 

Good idea, but the proc.txt documentation about /proc/<pid>/status (line
140) and the contents of the /proc/<pid>/stat file (line 192) is
complete outdated. And there is also no documentation
about /proc/<pid>/*maps. 

So i want to try to fix the missing documentation in proc.txt in a
separate patch. Will this okay by you?

Greetings


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-05 19:12         ` Stefani Seibold
@ 2009-06-05 19:19           ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-05 19:19 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Fri, 05 Jun 2009 21:12:56 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> So i want to try to fix the missing documentation in proc.txt in a
> separate patch. Will this okay by you?

That would be great, thanks.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-06-05 19:19           ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-05 19:19 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Fri, 05 Jun 2009 21:12:56 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> So i want to try to fix the missing documentation in proc.txt in a
> separate patch. Will this okay by you?

That would be great, thanks.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads V0.6
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-06 10:01     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-06 10:01 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: a7f124b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Fix missing mm->mmap_sem locking in function task_show_stack_usage()
 - Code cleanup

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

The update of the Documentations/filesystems/procfs.txt will follow in a
future patch, because it is outdated and a want to fix the entry for the
status, stat, maps and smaps entries.
 
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
 
 fs/exec.c             |    2 +
 fs/proc/array.c       |   51 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 69 insertions(+), 1 deletion(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] procfs: provide stack information for threads V0.6
@ 2009-06-06 10:01     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-06 10:01 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: a7f124b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - Fix missing mm->mmap_sem locking in function task_show_stack_usage()
 - Code cleanup

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

The update of the Documentations/filesystems/procfs.txt will follow in a
future patch, because it is outdated and a want to fix the entry for the
status, stat, maps and smaps entries.
 
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
 
 fs/exec.c             |    2 +
 fs/proc/array.c       |   51 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c    |   14 +++++++++++++
 include/linux/sched.h |    1 
 kernel/fork.c         |    2 +
 5 files changed, 69 insertions(+), 1 deletion(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] proc.txt: Update kernel filesystem/proc.txt documentation
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-09 10:35     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-09 10:35 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is a patch against the file Documentation/filesystem/proc.txt.

It is an update for the "Process-Specific Subdirectories" to reflect 
the changes till kernel 2.6.30. It also introduce the my 
"provide stack information for threads".
 
 proc.txt |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 176 insertions(+), 34 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/Documentation/filesystems/proc.txt linux-2.6.30/Documentation/filesystems/proc.txt
--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-04 09:29:43.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-09 12:26:25.000000000 +0200
@@ -10,6 +10,7 @@
 Version 1.3                                              Kernel version 2.2.12
 					      Kernel version 2.4.0-test11-pre4
 ------------------------------------------------------------------------------
+2.6.30 fixes/update  Stefani Seibold <stefani@seibold.net>      June 9 2009
 
 Table of Contents
 -----------------
@@ -134,7 +135,8 @@
  status		Process status in human readable form
  wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
- smaps		Extension based on maps, the rss size for each mapped file
+ smaps		a extension based on maps, showing the memory consumption of
+               each mapping
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
@@ -143,37 +145,95 @@
   >cat /proc/self/status 
   Name:   cat 
   State:  R (running) 
+  Tgid:   5452
   Pid:    5452 
   PPid:   743 
   TracerPid:      0						(2.4)
   Uid:    501     501     501     501 
   Gid:    100     100     100     100 
+  FDSize: 256
   Groups: 100 14 16 
-  VmSize:     1112 kB 
+  VmPeak:     5004 kB 
+  VmSize:     5004 kB 
   VmLck:         0 kB 
-  VmRSS:       348 kB 
-  VmData:       24 kB 
-  VmStk:        12 kB 
-  VmExe:         8 kB 
-  VmLib:      1044 kB 
+  VmHWM:       476 kB 
+  VmRSS:       476 kB 
+  VmData:      156 kB 
+  VmStk:        88 kB 
+  VmExe:        68 kB 
+  VmLib:      1412 kB 
+  VmPTE:        20 kb
+  Threads:        1
+  SigQ:   0/28578
   SigPnd: 0000000000000000 
+  ShdPnd: 0000000000000000 
   SigBlk: 0000000000000000 
   SigIgn: 0000000000000000 
   SigCgt: 0000000000000000 
   CapInh: 00000000fffffeff 
   CapPrm: 0000000000000000 
   CapEff: 0000000000000000 
-
+  CapBnd: ffffffffffffffff
+  voluntary_ctxt_switches:        0
+  nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
-information. The  statm  file  contains  more  detailed  information about the
-process memory usage. Its seven fields are explained in Table 1-2.  The stat
-file contains details information about the process itself.  Its fields are
-explained in Table 1-3.
+information.  But you get a more detailed  view of the  process by reading the
+file /proc/PID/status. It fields are described in table 1-2.
 
+The  statm  file  contains  more  detailed  information about the process
+memory usage. Its seven fields are explained in Table 1-3.  The stat file
+contains details information about the process itself.  Its fields are
+explained in Table 1-4.
+
+Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+..............................................................................
+ Field                       Content
+ Name                        filename of the executable
+ State                       state (R is running, S is sleeping, D is sleeping
+                             in an uninterruptible wait, Z is zombie,
+			     T is traced or stopped)
+ Tgid                        thread group ID
+ Pid                         process id
+ PPid                        process id of the parent process
+ TracerPid                   PID of process tracing this process (0 if not) 
+ Uid                         Real, effective, saved set, and  file system UIDs
+ Gid                         Real, effective, saved set, and  file system GIDs
+ FDSize                      number of file descriptor slots currently allocated
+ Groups                      supplementary group list
+ VmPeak                      peak virtual memory size
+ VmSize                      total program size
+ VmLck                       locked memory size
+ VmHWM                       peak resident set size ("high water mark")
+ VmRSS                       size of memory portions
+ VmData                      size of data, stack, and text segments
+ VmStk                       size of data, stack, and text segments
+ VmExe                       size of text segment
+ VmLib                       size of shared library code
+ VmPTE                       size of page table entries
+ Threads                     number of threads
+ SigQ                        number of signals queued/max. number for queue
+ SigPnd                      bitmap of pending signals for the thread
+ ShdPnd                      bitmap of shared pending signals for the process
+ SigBlk                      bitmap of blocked signals
+ SigIgn                      bitmap of ignored signals
+ SigCgt                      bitmap of catched signals
+ CapInh                      bitmap of inheritable capabilities
+ CapPrm                      bitmap of permitted capabilities
+ CapEff                      bitmap of effective capabilities
+ CapBnd                      bitmap of capabilities bounding set
+ Cpus_allowed                mask of CPUs on which this process may run
+ Cpus_allowed_list           Same as previous, but in "list format"
+ Mems_allowed                mask of memory nodes allowed to this process
+ Mems_allowed_list           Same as previous, but in "list format"
+ voluntary_ctxt_switches     number of voluntary context switches
+ nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
+..............................................................................
 
-Table 1-2: Contents of the statm files (as of 2.6.8-rc3)
+Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
 ..............................................................................
  Field    Content
  size     total program size (pages)		(same as VmSize in status)
@@ -188,7 +248,7 @@
 ..............................................................................
 
 
-Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
+Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
 ..............................................................................
  Field          Content
   pid           process id
@@ -222,10 +282,10 @@
   start_stack   address of the start of the stack
   esp           current value of ESP
   eip           current value of EIP
-  pending       bitmap of pending signals (obsolete)
-  blocked       bitmap of blocked signals (obsolete)
-  sigign        bitmap of ignored signals (obsolete)
-  sigcatch      bitmap of catched signals (obsolete)
+  pending       bitmap of pending signals
+  blocked       bitmap of blocked signals
+  sigign        bitmap of ignored signals
+  sigcatch      bitmap of catched signals
   wchan         address where process went to sleep
   0             (place holder)
   0             (place holder)
@@ -234,19 +294,101 @@
   rt_priority   realtime priority
   policy        scheduling policy (man sched_setscheduler)
   blkio_ticks   time spent waiting for block IO
+  gtime         guest time of the task in jiffies
+  cgtime        guest time of the task children in jiffies
 ..............................................................................
 
+The /proc/PID/map file containing the currently mapped memory regions and
+their access permissions.
+
+The format is:
+
+address           perms offset  dev   inode      pathname
+
+08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
+08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
+0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
+a7cb1000-a7cb2000 ---p 00000000 00:00 0 
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: a7eb14b4]
+a7eb2000-a7eb3000 ---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
+a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
+a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
+a800b000-a800e000 rw-p 00000000 00:00 0 
+a800e000-a8022000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
+a8022000-a8023000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
+a8023000-a8024000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
+a8024000-a8027000 rw-p 00000000 00:00 0 
+a8027000-a8043000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
+a8043000-a8044000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
+a8044000-a8045000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
+aff35000-aff4a000 rw-p 00000000 00:00 0          [stack]
+ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
+
+where "address" is the address space in the process that it occupies, "perms"
+is a set of permissions:
+
+ r = read
+ w = write
+ x = execute
+ s = shared
+ p = private (copy on write)
+
+"offset" is the offset into the mapping, "dev" is the device (major:minor), and
+"inode" is the inode  on that device.  0 indicates that  no inode is associated
+with the memory region, as the case would be with BSS (uninitialized data).
+The "pathname" shows the name associated file for this mapping.  If the mapping
+is not associated with a file:
+
+ [heap]                   = the heap of the program
+ [stack]                  = the stack of the main process
+ [vdso]                   = the "virtual dynamic shared object",
+                            the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the starting
+                            address of the stack
+
+ or if empty, the mapping is anonymous.
+
+
+The /proc/PID/smaps is an extension based on maps, showing the memory
+consumption for each of the process's mappings. For each of mappings there
+is a series of lines such as the following:
+
+08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash
+Size:               1084 kB
+Rss:                 892 kB
+Pss:                 374 kB
+Shared_Clean:        892 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:          892 kB
+Swap:                  0 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+
+The first  of these lines shows  the same information  as is displayed for the
+mapping in /proc/PID/maps.  The remaining lines show  the size of the mapping,
+the amount of the mapping that is currently resident in RAM, the "proportional
+set size” (divide each shared page by the number of processes sharing it), the
+number of clean and dirty shared pages in the mapping, and the number of clean
+and dirty private pages in the mapping.  The "Referenced" indicates the amount
+of memory currently marked as referenced or accessed.
+
+This file is only present if the CONFIG_MMU kernel configuration option is 
+enabled.
 
 1.2 Kernel data
 ---------------
 
 Similar to  the  process entries, the kernel data files give information about
 the running kernel. The files used to obtain this information are contained in
-/proc and  are  listed  in Table 1-4. Not all of these will be present in your
+/proc and  are  listed  in Table 1-5. Not all of these will be present in your
 system. It  depends  on the kernel configuration and the loaded modules, which
 files are there, and which are missing.
 
-Table 1-4: Kernel info in /proc
+Table 1-5: Kernel info in /proc
 ..............................................................................
  File        Content                                           
  apm         Advanced power management info                    
@@ -614,10 +756,10 @@
 
 More detailed  information  can  be  found  in  the  controller  specific
 subdirectories. These  are  named  ide0,  ide1  and  so  on.  Each  of  these
-directories contains the files shown in table 1-5.
+directories contains the files shown in table 1-6.
 
 
-Table 1-5: IDE controller info in  /proc/ide/ide?
+Table 1-6: IDE controller info in  /proc/ide/ide?
 ..............................................................................
  File    Content                                 
  channel IDE channel (0 or 1)                    
@@ -627,11 +769,11 @@
 ..............................................................................
 
 Each device  connected  to  a  controller  has  a separate subdirectory in the
-controllers directory.  The  files  listed in table 1-6 are contained in these
+controllers directory.  The  files  listed in table 1-7 are contained in these
 directories.
 
 
-Table 1-6: IDE device information
+Table 1-7: IDE device information
 ..............................................................................
  File             Content                                    
  cache            The cache                                  
@@ -673,12 +815,12 @@
 1.4 Networking info in /proc/net
 --------------------------------
 
-The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-6 shows the
+The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-8 shows the
 additional values  you  get  for  IP  version 6 if you configure the kernel to
-support this. Table 1-7 lists the files and their meaning.
+support this. Table 1-9 lists the files and their meaning.
 
 
-Table 1-6: IPv6 info in /proc/net 
+Table 1-8: IPv6 info in /proc/net 
 ..............................................................................
  File       Content                                               
  udp6       UDP sockets (IPv6)                                    
@@ -693,7 +835,7 @@
 ..............................................................................
 
 
-Table 1-7: Network info in /proc/net 
+Table 1-9: Network info in /proc/net 
 ..............................................................................
  File          Content                                                         
  arp           Kernel  ARP table                                               
@@ -817,10 +959,10 @@
 your system.  It  has  one  subdirectory  for  each port, named after the port
 number (0,1,2,...).
 
-These directories contain the four files shown in Table 1-8.
+These directories contain the four files shown in Table 1-10.
 
 
-Table 1-8: Files in /proc/parport 
+Table 1-10: Files in /proc/parport 
 ..............................................................................
  File      Content                                                             
  autoprobe Any IEEE-1284 device ID information that has been acquired.         
@@ -838,10 +980,10 @@
 
 Information about  the  available  and actually used tty's can be found in the
 directory /proc/tty.You'll  find  entries  for drivers and line disciplines in
-this directory, as shown in Table 1-9.
+this directory, as shown in Table 1-11.
 
 
-Table 1-9: Files in /proc/tty 
+Table 1-11: Files in /proc/tty 
 ..............................................................................
  File          Content                                        
  drivers       list of drivers and their usage                
@@ -926,9 +1068,9 @@
 /proc/fs/ext4.  Each mounted filesystem will have a directory in
 /proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
 /proc/fs/ext4/dm-0).   The files in each per-device directory are shown
-in Table 1-10, below.
+in Table 1-12, below.
 
-Table 1-10: Files in /proc/fs/ext4/<devname>
+Table 1-12: Files in /proc/fs/ext4/<devname>
 ..............................................................................
  File            Content                                        
  mb_groups       details of multiblock allocator buddy cache of free blocks



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch] proc.txt: Update kernel filesystem/proc.txt documentation
@ 2009-06-09 10:35     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-09 10:35 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is a patch against the file Documentation/filesystem/proc.txt.

It is an update for the "Process-Specific Subdirectories" to reflect 
the changes till kernel 2.6.30. It also introduce the my 
"provide stack information for threads".
 
 proc.txt |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 176 insertions(+), 34 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/Documentation/filesystems/proc.txt linux-2.6.30/Documentation/filesystems/proc.txt
--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-04 09:29:43.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-09 12:26:25.000000000 +0200
@@ -10,6 +10,7 @@
 Version 1.3                                              Kernel version 2.2.12
 					      Kernel version 2.4.0-test11-pre4
 ------------------------------------------------------------------------------
+2.6.30 fixes/update  Stefani Seibold <stefani@seibold.net>      June 9 2009
 
 Table of Contents
 -----------------
@@ -134,7 +135,8 @@
  status		Process status in human readable form
  wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
- smaps		Extension based on maps, the rss size for each mapped file
+ smaps		a extension based on maps, showing the memory consumption of
+               each mapping
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
@@ -143,37 +145,95 @@
   >cat /proc/self/status 
   Name:   cat 
   State:  R (running) 
+  Tgid:   5452
   Pid:    5452 
   PPid:   743 
   TracerPid:      0						(2.4)
   Uid:    501     501     501     501 
   Gid:    100     100     100     100 
+  FDSize: 256
   Groups: 100 14 16 
-  VmSize:     1112 kB 
+  VmPeak:     5004 kB 
+  VmSize:     5004 kB 
   VmLck:         0 kB 
-  VmRSS:       348 kB 
-  VmData:       24 kB 
-  VmStk:        12 kB 
-  VmExe:         8 kB 
-  VmLib:      1044 kB 
+  VmHWM:       476 kB 
+  VmRSS:       476 kB 
+  VmData:      156 kB 
+  VmStk:        88 kB 
+  VmExe:        68 kB 
+  VmLib:      1412 kB 
+  VmPTE:        20 kb
+  Threads:        1
+  SigQ:   0/28578
   SigPnd: 0000000000000000 
+  ShdPnd: 0000000000000000 
   SigBlk: 0000000000000000 
   SigIgn: 0000000000000000 
   SigCgt: 0000000000000000 
   CapInh: 00000000fffffeff 
   CapPrm: 0000000000000000 
   CapEff: 0000000000000000 
-
+  CapBnd: ffffffffffffffff
+  voluntary_ctxt_switches:        0
+  nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
-information. The  statm  file  contains  more  detailed  information about the
-process memory usage. Its seven fields are explained in Table 1-2.  The stat
-file contains details information about the process itself.  Its fields are
-explained in Table 1-3.
+information.  But you get a more detailed  view of the  process by reading the
+file /proc/PID/status. It fields are described in table 1-2.
 
+The  statm  file  contains  more  detailed  information about the process
+memory usage. Its seven fields are explained in Table 1-3.  The stat file
+contains details information about the process itself.  Its fields are
+explained in Table 1-4.
+
+Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+..............................................................................
+ Field                       Content
+ Name                        filename of the executable
+ State                       state (R is running, S is sleeping, D is sleeping
+                             in an uninterruptible wait, Z is zombie,
+			     T is traced or stopped)
+ Tgid                        thread group ID
+ Pid                         process id
+ PPid                        process id of the parent process
+ TracerPid                   PID of process tracing this process (0 if not) 
+ Uid                         Real, effective, saved set, and  file system UIDs
+ Gid                         Real, effective, saved set, and  file system GIDs
+ FDSize                      number of file descriptor slots currently allocated
+ Groups                      supplementary group list
+ VmPeak                      peak virtual memory size
+ VmSize                      total program size
+ VmLck                       locked memory size
+ VmHWM                       peak resident set size ("high water mark")
+ VmRSS                       size of memory portions
+ VmData                      size of data, stack, and text segments
+ VmStk                       size of data, stack, and text segments
+ VmExe                       size of text segment
+ VmLib                       size of shared library code
+ VmPTE                       size of page table entries
+ Threads                     number of threads
+ SigQ                        number of signals queued/max. number for queue
+ SigPnd                      bitmap of pending signals for the thread
+ ShdPnd                      bitmap of shared pending signals for the process
+ SigBlk                      bitmap of blocked signals
+ SigIgn                      bitmap of ignored signals
+ SigCgt                      bitmap of catched signals
+ CapInh                      bitmap of inheritable capabilities
+ CapPrm                      bitmap of permitted capabilities
+ CapEff                      bitmap of effective capabilities
+ CapBnd                      bitmap of capabilities bounding set
+ Cpus_allowed                mask of CPUs on which this process may run
+ Cpus_allowed_list           Same as previous, but in "list format"
+ Mems_allowed                mask of memory nodes allowed to this process
+ Mems_allowed_list           Same as previous, but in "list format"
+ voluntary_ctxt_switches     number of voluntary context switches
+ nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
+..............................................................................
 
-Table 1-2: Contents of the statm files (as of 2.6.8-rc3)
+Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
 ..............................................................................
  Field    Content
  size     total program size (pages)		(same as VmSize in status)
@@ -188,7 +248,7 @@
 ..............................................................................
 
 
-Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
+Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
 ..............................................................................
  Field          Content
   pid           process id
@@ -222,10 +282,10 @@
   start_stack   address of the start of the stack
   esp           current value of ESP
   eip           current value of EIP
-  pending       bitmap of pending signals (obsolete)
-  blocked       bitmap of blocked signals (obsolete)
-  sigign        bitmap of ignored signals (obsolete)
-  sigcatch      bitmap of catched signals (obsolete)
+  pending       bitmap of pending signals
+  blocked       bitmap of blocked signals
+  sigign        bitmap of ignored signals
+  sigcatch      bitmap of catched signals
   wchan         address where process went to sleep
   0             (place holder)
   0             (place holder)
@@ -234,19 +294,101 @@
   rt_priority   realtime priority
   policy        scheduling policy (man sched_setscheduler)
   blkio_ticks   time spent waiting for block IO
+  gtime         guest time of the task in jiffies
+  cgtime        guest time of the task children in jiffies
 ..............................................................................
 
+The /proc/PID/map file containing the currently mapped memory regions and
+their access permissions.
+
+The format is:
+
+address           perms offset  dev   inode      pathname
+
+08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
+08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
+0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
+a7cb1000-a7cb2000 ---p 00000000 00:00 0 
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: a7eb14b4]
+a7eb2000-a7eb3000 ---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
+a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
+a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
+a800b000-a800e000 rw-p 00000000 00:00 0 
+a800e000-a8022000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
+a8022000-a8023000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
+a8023000-a8024000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
+a8024000-a8027000 rw-p 00000000 00:00 0 
+a8027000-a8043000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
+a8043000-a8044000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
+a8044000-a8045000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
+aff35000-aff4a000 rw-p 00000000 00:00 0          [stack]
+ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
+
+where "address" is the address space in the process that it occupies, "perms"
+is a set of permissions:
+
+ r = read
+ w = write
+ x = execute
+ s = shared
+ p = private (copy on write)
+
+"offset" is the offset into the mapping, "dev" is the device (major:minor), and
+"inode" is the inode  on that device.  0 indicates that  no inode is associated
+with the memory region, as the case would be with BSS (uninitialized data).
+The "pathname" shows the name associated file for this mapping.  If the mapping
+is not associated with a file:
+
+ [heap]                   = the heap of the program
+ [stack]                  = the stack of the main process
+ [vdso]                   = the "virtual dynamic shared object",
+                            the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the starting
+                            address of the stack
+
+ or if empty, the mapping is anonymous.
+
+
+The /proc/PID/smaps is an extension based on maps, showing the memory
+consumption for each of the process's mappings. For each of mappings there
+is a series of lines such as the following:
+
+08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash
+Size:               1084 kB
+Rss:                 892 kB
+Pss:                 374 kB
+Shared_Clean:        892 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:          892 kB
+Swap:                  0 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+
+The first  of these lines shows  the same information  as is displayed for the
+mapping in /proc/PID/maps.  The remaining lines show  the size of the mapping,
+the amount of the mapping that is currently resident in RAM, the "proportional
+set size” (divide each shared page by the number of processes sharing it), the
+number of clean and dirty shared pages in the mapping, and the number of clean
+and dirty private pages in the mapping.  The "Referenced" indicates the amount
+of memory currently marked as referenced or accessed.
+
+This file is only present if the CONFIG_MMU kernel configuration option is 
+enabled.
 
 1.2 Kernel data
 ---------------
 
 Similar to  the  process entries, the kernel data files give information about
 the running kernel. The files used to obtain this information are contained in
-/proc and  are  listed  in Table 1-4. Not all of these will be present in your
+/proc and  are  listed  in Table 1-5. Not all of these will be present in your
 system. It  depends  on the kernel configuration and the loaded modules, which
 files are there, and which are missing.
 
-Table 1-4: Kernel info in /proc
+Table 1-5: Kernel info in /proc
 ..............................................................................
  File        Content                                           
  apm         Advanced power management info                    
@@ -614,10 +756,10 @@
 
 More detailed  information  can  be  found  in  the  controller  specific
 subdirectories. These  are  named  ide0,  ide1  and  so  on.  Each  of  these
-directories contains the files shown in table 1-5.
+directories contains the files shown in table 1-6.
 
 
-Table 1-5: IDE controller info in  /proc/ide/ide?
+Table 1-6: IDE controller info in  /proc/ide/ide?
 ..............................................................................
  File    Content                                 
  channel IDE channel (0 or 1)                    
@@ -627,11 +769,11 @@
 ..............................................................................
 
 Each device  connected  to  a  controller  has  a separate subdirectory in the
-controllers directory.  The  files  listed in table 1-6 are contained in these
+controllers directory.  The  files  listed in table 1-7 are contained in these
 directories.
 
 
-Table 1-6: IDE device information
+Table 1-7: IDE device information
 ..............................................................................
  File             Content                                    
  cache            The cache                                  
@@ -673,12 +815,12 @@
 1.4 Networking info in /proc/net
 --------------------------------
 
-The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-6 shows the
+The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-8 shows the
 additional values  you  get  for  IP  version 6 if you configure the kernel to
-support this. Table 1-7 lists the files and their meaning.
+support this. Table 1-9 lists the files and their meaning.
 
 
-Table 1-6: IPv6 info in /proc/net 
+Table 1-8: IPv6 info in /proc/net 
 ..............................................................................
  File       Content                                               
  udp6       UDP sockets (IPv6)                                    
@@ -693,7 +835,7 @@
 ..............................................................................
 
 
-Table 1-7: Network info in /proc/net 
+Table 1-9: Network info in /proc/net 
 ..............................................................................
  File          Content                                                         
  arp           Kernel  ARP table                                               
@@ -817,10 +959,10 @@
 your system.  It  has  one  subdirectory  for  each port, named after the port
 number (0,1,2,...).
 
-These directories contain the four files shown in Table 1-8.
+These directories contain the four files shown in Table 1-10.
 
 
-Table 1-8: Files in /proc/parport 
+Table 1-10: Files in /proc/parport 
 ..............................................................................
  File      Content                                                             
  autoprobe Any IEEE-1284 device ID information that has been acquired.         
@@ -838,10 +980,10 @@
 
 Information about  the  available  and actually used tty's can be found in the
 directory /proc/tty.You'll  find  entries  for drivers and line disciplines in
-this directory, as shown in Table 1-9.
+this directory, as shown in Table 1-11.
 
 
-Table 1-9: Files in /proc/tty 
+Table 1-11: Files in /proc/tty 
 ..............................................................................
  File          Content                                        
  drivers       list of drivers and their usage                
@@ -926,9 +1068,9 @@
 /proc/fs/ext4.  Each mounted filesystem will have a directory in
 /proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
 /proc/fs/ext4/dm-0).   The files in each per-device directory are shown
-in Table 1-10, below.
+in Table 1-12, below.
 
-Table 1-10: Files in /proc/fs/ext4/<devname>
+Table 1-12: Files in /proc/fs/ext4/<devname>
 ..............................................................................
  File            Content                                        
  mb_groups       details of multiblock allocator buddy cache of free blocks


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
  2009-06-09 10:35     ` Stefani Seibold
@ 2009-06-09 19:36       ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-09 19:36 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Tue, 09 Jun 2009 12:35:58 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is a patch against the file Documentation/filesystem/proc.txt.
> 
> It is an update for the "Process-Specific Subdirectories" to reflect 
> the changes till kernel 2.6.30. It also introduce the my 
> "provide stack information for threads".

Sorry, but it would be much preferable to do this as two patches.  The
first fixes up proc.txt and the second adds the
stack-information-for-threads material.

This is because the two changes are quite conceptually distinct, and we
might end up wanting to merge one chage and not the other.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
@ 2009-06-09 19:36       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-09 19:36 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Tue, 09 Jun 2009 12:35:58 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is a patch against the file Documentation/filesystem/proc.txt.
> 
> It is an update for the "Process-Specific Subdirectories" to reflect 
> the changes till kernel 2.6.30. It also introduce the my 
> "provide stack information for threads".

Sorry, but it would be much preferable to do this as two patches.  The
first fixes up proc.txt and the second adds the
stack-information-for-threads material.

This is because the two changes are quite conceptually distinct, and we
might end up wanting to merge one chage and not the other.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
  2009-06-09 19:36       ` Andrew Morton
@ 2009-06-09 20:53         ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-09 20:53 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm

Am Dienstag, den 09.06.2009, 12:36 -0700 schrieb Andrew Morton:
> On Tue, 09 Jun 2009 12:35:58 +0200
> Stefani Seibold <stefani@seibold.net> wrote:
> 
> > This is a patch against the file Documentation/filesystem/proc.txt.
> > 
> > It is an update for the "Process-Specific Subdirectories" to reflect 
> > the changes till kernel 2.6.30. It also introduce the my 
> > "provide stack information for threads".
> 
> Sorry, but it would be much preferable to do this as two patches.  The
> first fixes up proc.txt and the second adds the
> stack-information-for-threads material.
> 

That is really frustrating. I did everything that you and ingo molnar
had complained.

What is wrong with the "provide stack information for threads"? It is a
very tiny patch which did not harm.

The only reason to fix and update the proc.txt was that you told me that
this is the last thing that you miss.

> This is because the two changes are quite conceptually distinct, and we
> might end up wanting to merge one chage and not the other.
> 

Okay, if the other patch will not included than it makes no sense for me
to get in the other.

Simple question: will you accept the thread stack info patch or not? If
yes, i will spent the time to split proc.txt patch.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
@ 2009-06-09 20:53         ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-09 20:53 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm

Am Dienstag, den 09.06.2009, 12:36 -0700 schrieb Andrew Morton:
> On Tue, 09 Jun 2009 12:35:58 +0200
> Stefani Seibold <stefani@seibold.net> wrote:
> 
> > This is a patch against the file Documentation/filesystem/proc.txt.
> > 
> > It is an update for the "Process-Specific Subdirectories" to reflect 
> > the changes till kernel 2.6.30. It also introduce the my 
> > "provide stack information for threads".
> 
> Sorry, but it would be much preferable to do this as two patches.  The
> first fixes up proc.txt and the second adds the
> stack-information-for-threads material.
> 

That is really frustrating. I did everything that you and ingo molnar
had complained.

What is wrong with the "provide stack information for threads"? It is a
very tiny patch which did not harm.

The only reason to fix and update the proc.txt was that you told me that
this is the last thing that you miss.

> This is because the two changes are quite conceptually distinct, and we
> might end up wanting to merge one chage and not the other.
> 

Okay, if the other patch will not included than it makes no sense for me
to get in the other.

Simple question: will you accept the thread stack info patch or not? If
yes, i will spent the time to split proc.txt patch.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
  2009-06-09 20:53         ` Stefani Seibold
@ 2009-06-09 21:13           ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-09 21:13 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Tue, 09 Jun 2009 22:53:27 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> Am Dienstag, den 09.06.2009, 12:36 -0700 schrieb Andrew Morton:
> > On Tue, 09 Jun 2009 12:35:58 +0200
> > Stefani Seibold <stefani@seibold.net> wrote:
> > 
> > > This is a patch against the file Documentation/filesystem/proc.txt.
> > > 
> > > It is an update for the "Process-Specific Subdirectories" to reflect 
> > > the changes till kernel 2.6.30. It also introduce the my 
> > > "provide stack information for threads".
> > 
> > Sorry, but it would be much preferable to do this as two patches.  The
> > first fixes up proc.txt and the second adds the
> > stack-information-for-threads material.
> > 
> 
> That is really frustrating. I did everything that you and ingo molnar
> had complained.
> 
> What is wrong with the "provide stack information for threads"? It is a
> very tiny patch which did not harm.
> 
> The only reason to fix and update the proc.txt was that you told me that
> this is the last thing that you miss.

It's more a procedural thing really.  We've learnt that it's best to
avoid mixing more than a single "concept" into a single patch.  For a
whole pile of reasons: reviewability, bisectability, revertability,
testability, etc.

In this case, it's unobvious which parts of the patch were specific to
the stack-information-for-threads changes and which parts were not. 
This makes it hard to review your proposed changes.

> > This is because the two changes are quite conceptually distinct, and we
> > might end up wanting to merge one chage and not the other.
> > 
> 
> Okay, if the other patch will not included than it makes no sense for me
> to get in the other.
> 
> Simple question: will you accept the thread stack info patch or not? If
> yes, i will spent the time to split proc.txt patch.
> 

It looks OK to me now.  If it passes testing and nobody has fatal
objections then yes, I expect it'll be merged in 2.6.31.

The way to organise these changes is

[patch 1/2] fix proc.txt
[patch 2/2] procfs: provide stack information for threads

The second patch will contain a small update to proc.txt.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] proc.txt: Update kernel filesystem/proc.txt documentation
@ 2009-06-09 21:13           ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-09 21:13 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm

On Tue, 09 Jun 2009 22:53:27 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> Am Dienstag, den 09.06.2009, 12:36 -0700 schrieb Andrew Morton:
> > On Tue, 09 Jun 2009 12:35:58 +0200
> > Stefani Seibold <stefani@seibold.net> wrote:
> > 
> > > This is a patch against the file Documentation/filesystem/proc.txt.
> > > 
> > > It is an update for the "Process-Specific Subdirectories" to reflect 
> > > the changes till kernel 2.6.30. It also introduce the my 
> > > "provide stack information for threads".
> > 
> > Sorry, but it would be much preferable to do this as two patches.  The
> > first fixes up proc.txt and the second adds the
> > stack-information-for-threads material.
> > 
> 
> That is really frustrating. I did everything that you and ingo molnar
> had complained.
> 
> What is wrong with the "provide stack information for threads"? It is a
> very tiny patch which did not harm.
> 
> The only reason to fix and update the proc.txt was that you told me that
> this is the last thing that you miss.

It's more a procedural thing really.  We've learnt that it's best to
avoid mixing more than a single "concept" into a single patch.  For a
whole pile of reasons: reviewability, bisectability, revertability,
testability, etc.

In this case, it's unobvious which parts of the patch were specific to
the stack-information-for-threads changes and which parts were not. 
This makes it hard to review your proposed changes.

> > This is because the two changes are quite conceptually distinct, and we
> > might end up wanting to merge one chage and not the other.
> > 
> 
> Okay, if the other patch will not included than it makes no sense for me
> to get in the other.
> 
> Simple question: will you accept the thread stack info patch or not? If
> yes, i will spent the time to split proc.txt patch.
> 

It looks OK to me now.  If it passes testing and nobody has fatal
objections then yes, I expect it'll be merged in 2.6.31.

The way to organise these changes is

[patch 1/2] fix proc.txt
[patch 2/2] procfs: provide stack information for threads

The second patch will contain a small update to proc.txt.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 1/2] proc.txt: Update kernel filesystem/proc.txt documentation
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-10  6:46     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  6:46 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is a patch against the file Documentation/filesystem/proc.txt.

It is an update for the "Process-Specific Subdirectories" to reflect 
the changes till kernel 2.6.30.

 proc.txt |  242 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 190 insertions(+), 52 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-04 09:29:43.000000000 +0200
+++ linux-2.6.30.patch/Documentation/filesystems/proc.txt	2009-06-10 08:18:35.000000000 +0200
@@ -5,11 +5,12 @@
                   Bodo Bauer <bb@ricochet.net>
 
 2.4.x update	  Jorge Nerin <comandante@zaralinux.com>      November 14 2000
-move /proc/sys	  Shen Feng <shen@cn.fujitsu.com>		    April 1 2009
+move /proc/sys	  Shen Feng <shen@cn.fujitsu.com>		  April 1 2009
 ------------------------------------------------------------------------------
 Version 1.3                                              Kernel version 2.2.12
 					      Kernel version 2.4.0-test11-pre4
 ------------------------------------------------------------------------------
+fixes/update part 1.1  Stefani Seibold <stefani@seibold.net>       June 9 2009
 
 Table of Contents
 -----------------
@@ -116,7 +117,7 @@
 subdirectory has the entries listed in Table 1-1.
 
 
-Table 1-1: Process specific entries in /proc 
+Table 1-1: Process specific entries in /proc
 ..............................................................................
  File		Content
  clear_refs	Clears page referenced bits shown in smaps output
@@ -134,46 +135,103 @@
  status		Process status in human readable form
  wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
- smaps		Extension based on maps, the rss size for each mapped file
+ smaps		a extension based on maps, showing the memory consumption of
+		each mapping
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
 read the file /proc/PID/status:
 
-  >cat /proc/self/status 
-  Name:   cat 
-  State:  R (running) 
-  Pid:    5452 
-  PPid:   743 
+  >cat /proc/self/status
+  Name:   cat
+  State:  R (running)
+  Tgid:   5452
+  Pid:    5452
+  PPid:   743
   TracerPid:      0						(2.4)
-  Uid:    501     501     501     501 
-  Gid:    100     100     100     100 
-  Groups: 100 14 16 
-  VmSize:     1112 kB 
-  VmLck:         0 kB 
-  VmRSS:       348 kB 
-  VmData:       24 kB 
-  VmStk:        12 kB 
-  VmExe:         8 kB 
-  VmLib:      1044 kB 
-  SigPnd: 0000000000000000 
-  SigBlk: 0000000000000000 
-  SigIgn: 0000000000000000 
-  SigCgt: 0000000000000000 
-  CapInh: 00000000fffffeff 
-  CapPrm: 0000000000000000 
-  CapEff: 0000000000000000 
-
+  Uid:    501     501     501     501
+  Gid:    100     100     100     100
+  FDSize: 256
+  Groups: 100 14 16
+  VmPeak:     5004 kB
+  VmSize:     5004 kB
+  VmLck:         0 kB
+  VmHWM:       476 kB
+  VmRSS:       476 kB
+  VmData:      156 kB
+  VmStk:        88 kB
+  VmExe:        68 kB
+  VmLib:      1412 kB
+  VmPTE:        20 kb
+  Threads:        1
+  SigQ:   0/28578
+  SigPnd: 0000000000000000
+  ShdPnd: 0000000000000000
+  SigBlk: 0000000000000000
+  SigIgn: 0000000000000000
+  SigCgt: 0000000000000000
+  CapInh: 00000000fffffeff
+  CapPrm: 0000000000000000
+  CapEff: 0000000000000000
+  CapBnd: ffffffffffffffff
+  voluntary_ctxt_switches:        0
+  nonvoluntary_ctxt_switches:     1
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
-information. The  statm  file  contains  more  detailed  information about the
-process memory usage. Its seven fields are explained in Table 1-2.  The stat
-file contains details information about the process itself.  Its fields are
-explained in Table 1-3.
+information.  But you get a more detailed  view of the  process by reading the
+file /proc/PID/status. It fields are described in table 1-2.
 
+The  statm  file  contains  more  detailed  information about the process
+memory usage. Its seven fields are explained in Table 1-3.  The stat file
+contains details information about the process itself.  Its fields are
+explained in Table 1-4.
+
+Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+..............................................................................
+ Field                       Content
+ Name                        filename of the executable
+ State                       state (R is running, S is sleeping, D is sleeping
+                             in an uninterruptible wait, Z is zombie,
+			     T is traced or stopped)
+ Tgid                        thread group ID
+ Pid                         process id
+ PPid                        process id of the parent process
+ TracerPid                   PID of process tracing this process (0 if not)
+ Uid                         Real, effective, saved set, and  file system UIDs
+ Gid                         Real, effective, saved set, and  file system GIDs
+ FDSize                      number of file descriptor slots currently allocated
+ Groups                      supplementary group list
+ VmPeak                      peak virtual memory size
+ VmSize                      total program size
+ VmLck                       locked memory size
+ VmHWM                       peak resident set size ("high water mark")
+ VmRSS                       size of memory portions
+ VmData                      size of data, stack, and text segments
+ VmStk                       size of data, stack, and text segments
+ VmExe                       size of text segment
+ VmLib                       size of shared library code
+ VmPTE                       size of page table entries
+ Threads                     number of threads
+ SigQ                        number of signals queued/max. number for queue
+ SigPnd                      bitmap of pending signals for the thread
+ ShdPnd                      bitmap of shared pending signals for the process
+ SigBlk                      bitmap of blocked signals
+ SigIgn                      bitmap of ignored signals
+ SigCgt                      bitmap of catched signals
+ CapInh                      bitmap of inheritable capabilities
+ CapPrm                      bitmap of permitted capabilities
+ CapEff                      bitmap of effective capabilities
+ CapBnd                      bitmap of capabilities bounding set
+ Cpus_allowed                mask of CPUs on which this process may run
+ Cpus_allowed_list           Same as previous, but in "list format"
+ Mems_allowed                mask of memory nodes allowed to this process
+ Mems_allowed_list           Same as previous, but in "list format"
+ voluntary_ctxt_switches     number of voluntary context switches
+ nonvoluntary_ctxt_switches  number of non voluntary context switches
+..............................................................................
 
-Table 1-2: Contents of the statm files (as of 2.6.8-rc3)
+Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
 ..............................................................................
  Field    Content
  size     total program size (pages)		(same as VmSize in status)
@@ -188,7 +246,7 @@
 ..............................................................................
 
 
-Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
+Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
 ..............................................................................
  Field          Content
   pid           process id
@@ -222,10 +280,10 @@
   start_stack   address of the start of the stack
   esp           current value of ESP
   eip           current value of EIP
-  pending       bitmap of pending signals (obsolete)
-  blocked       bitmap of blocked signals (obsolete)
-  sigign        bitmap of ignored signals (obsolete)
-  sigcatch      bitmap of catched signals (obsolete)
+  pending       bitmap of pending signals
+  blocked       bitmap of blocked signals
+  sigign        bitmap of ignored signals
+  sigcatch      bitmap of catched signals
   wchan         address where process went to sleep
   0             (place holder)
   0             (place holder)
@@ -234,19 +292,99 @@
   rt_priority   realtime priority
   policy        scheduling policy (man sched_setscheduler)
   blkio_ticks   time spent waiting for block IO
+  gtime         guest time of the task in jiffies
+  cgtime        guest time of the task children in jiffies
 ..............................................................................
 
+The /proc/PID/map file containing the currently mapped memory regions and
+their access permissions.
+
+The format is:
+
+address           perms offset  dev   inode      pathname
+
+08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
+08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
+0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
+a7cb1000-a7cb2000 ---p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7eb2000-a7eb3000 ---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
+a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
+a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
+a800b000-a800e000 rw-p 00000000 00:00 0
+a800e000-a8022000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
+a8022000-a8023000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
+a8023000-a8024000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
+a8024000-a8027000 rw-p 00000000 00:00 0
+a8027000-a8043000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
+a8043000-a8044000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
+a8044000-a8045000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
+aff35000-aff4a000 rw-p 00000000 00:00 0          [stack]
+ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
+
+where "address" is the address space in the process that it occupies, "perms"
+is a set of permissions:
+
+ r = read
+ w = write
+ x = execute
+ s = shared
+ p = private (copy on write)
+
+"offset" is the offset into the mapping, "dev" is the device (major:minor), and
+"inode" is the inode  on that device.  0 indicates that  no inode is associated
+with the memory region, as the case would be with BSS (uninitialized data).
+The "pathname" shows the name associated file for this mapping.  If the mapping
+is not associated with a file:
+
+ [heap]                   = the heap of the program
+ [stack]                  = the stack of the main process
+ [vdso]                   = the "virtual dynamic shared object",
+                            the kernel system call handler
+
+ or if empty, the mapping is anonymous.
+
+
+The /proc/PID/smaps is an extension based on maps, showing the memory
+consumption for each of the process's mappings. For each of mappings there
+is a series of lines such as the following:
+
+08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash
+Size:               1084 kB
+Rss:                 892 kB
+Pss:                 374 kB
+Shared_Clean:        892 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:          892 kB
+Swap:                  0 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+
+The first  of these lines shows  the same information  as is displayed for the
+mapping in /proc/PID/maps.  The remaining lines show  the size of the mapping,
+the amount of the mapping that is currently resident in RAM, the "proportional
+set size” (divide each shared page by the number of processes sharing it), the
+number of clean and dirty shared pages in the mapping, and the number of clean
+and dirty private pages in the mapping.  The "Referenced" indicates the amount
+of memory currently marked as referenced or accessed.
+
+This file is only present if the CONFIG_MMU kernel configuration option is
+enabled.
 
 1.2 Kernel data
 ---------------
 
 Similar to  the  process entries, the kernel data files give information about
 the running kernel. The files used to obtain this information are contained in
-/proc and  are  listed  in Table 1-4. Not all of these will be present in your
+/proc and  are  listed  in Table 1-5. Not all of these will be present in your
 system. It  depends  on the kernel configuration and the loaded modules, which
 files are there, and which are missing.
 
-Table 1-4: Kernel info in /proc
+Table 1-5: Kernel info in /proc
 ..............................................................................
  File        Content                                           
  apm         Advanced power management info                    
@@ -614,10 +752,10 @@
 
 More detailed  information  can  be  found  in  the  controller  specific
 subdirectories. These  are  named  ide0,  ide1  and  so  on.  Each  of  these
-directories contains the files shown in table 1-5.
+directories contains the files shown in table 1-6.
 
 
-Table 1-5: IDE controller info in  /proc/ide/ide?
+Table 1-6: IDE controller info in  /proc/ide/ide?
 ..............................................................................
  File    Content                                 
  channel IDE channel (0 or 1)                    
@@ -627,11 +765,11 @@
 ..............................................................................
 
 Each device  connected  to  a  controller  has  a separate subdirectory in the
-controllers directory.  The  files  listed in table 1-6 are contained in these
+controllers directory.  The  files  listed in table 1-7 are contained in these
 directories.
 
 
-Table 1-6: IDE device information
+Table 1-7: IDE device information
 ..............................................................................
  File             Content                                    
  cache            The cache                                  
@@ -673,12 +811,12 @@
 1.4 Networking info in /proc/net
 --------------------------------
 
-The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-6 shows the
+The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-8 shows the
 additional values  you  get  for  IP  version 6 if you configure the kernel to
-support this. Table 1-7 lists the files and their meaning.
+support this. Table 1-9 lists the files and their meaning.
 
 
-Table 1-6: IPv6 info in /proc/net 
+Table 1-8: IPv6 info in /proc/net 
 ..............................................................................
  File       Content                                               
  udp6       UDP sockets (IPv6)                                    
@@ -693,7 +831,7 @@
 ..............................................................................
 
 
-Table 1-7: Network info in /proc/net 
+Table 1-9: Network info in /proc/net 
 ..............................................................................
  File          Content                                                         
  arp           Kernel  ARP table                                               
@@ -817,10 +955,10 @@
 your system.  It  has  one  subdirectory  for  each port, named after the port
 number (0,1,2,...).
 
-These directories contain the four files shown in Table 1-8.
+These directories contain the four files shown in Table 1-10.
 
 
-Table 1-8: Files in /proc/parport 
+Table 1-10: Files in /proc/parport 
 ..............................................................................
  File      Content                                                             
  autoprobe Any IEEE-1284 device ID information that has been acquired.         
@@ -838,10 +976,10 @@
 
 Information about  the  available  and actually used tty's can be found in the
 directory /proc/tty.You'll  find  entries  for drivers and line disciplines in
-this directory, as shown in Table 1-9.
+this directory, as shown in Table 1-11.
 
 
-Table 1-9: Files in /proc/tty 
+Table 1-11: Files in /proc/tty 
 ..............................................................................
  File          Content                                        
  drivers       list of drivers and their usage                
@@ -926,9 +1064,9 @@
 /proc/fs/ext4.  Each mounted filesystem will have a directory in
 /proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
 /proc/fs/ext4/dm-0).   The files in each per-device directory are shown
-in Table 1-10, below.
+in Table 1-12, below.
 
-Table 1-10: Files in /proc/fs/ext4/<devname>
+Table 1-12: Files in /proc/fs/ext4/<devname>
 ..............................................................................
  File            Content                                        
  mb_groups       details of multiblock allocator buddy cache of free blocks



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 1/2] proc.txt: Update kernel filesystem/proc.txt documentation
@ 2009-06-10  6:46     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  6:46 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is a patch against the file Documentation/filesystem/proc.txt.

It is an update for the "Process-Specific Subdirectories" to reflect 
the changes till kernel 2.6.30.

 proc.txt |  242 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 190 insertions(+), 52 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-04 09:29:43.000000000 +0200
+++ linux-2.6.30.patch/Documentation/filesystems/proc.txt	2009-06-10 08:18:35.000000000 +0200
@@ -5,11 +5,12 @@
                   Bodo Bauer <bb@ricochet.net>
 
 2.4.x update	  Jorge Nerin <comandante@zaralinux.com>      November 14 2000
-move /proc/sys	  Shen Feng <shen@cn.fujitsu.com>		    April 1 2009
+move /proc/sys	  Shen Feng <shen@cn.fujitsu.com>		  April 1 2009
 ------------------------------------------------------------------------------
 Version 1.3                                              Kernel version 2.2.12
 					      Kernel version 2.4.0-test11-pre4
 ------------------------------------------------------------------------------
+fixes/update part 1.1  Stefani Seibold <stefani@seibold.net>       June 9 2009
 
 Table of Contents
 -----------------
@@ -116,7 +117,7 @@
 subdirectory has the entries listed in Table 1-1.
 
 
-Table 1-1: Process specific entries in /proc 
+Table 1-1: Process specific entries in /proc
 ..............................................................................
  File		Content
  clear_refs	Clears page referenced bits shown in smaps output
@@ -134,46 +135,103 @@
  status		Process status in human readable form
  wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
- smaps		Extension based on maps, the rss size for each mapped file
+ smaps		a extension based on maps, showing the memory consumption of
+		each mapping
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
 read the file /proc/PID/status:
 
-  >cat /proc/self/status 
-  Name:   cat 
-  State:  R (running) 
-  Pid:    5452 
-  PPid:   743 
+  >cat /proc/self/status
+  Name:   cat
+  State:  R (running)
+  Tgid:   5452
+  Pid:    5452
+  PPid:   743
   TracerPid:      0						(2.4)
-  Uid:    501     501     501     501 
-  Gid:    100     100     100     100 
-  Groups: 100 14 16 
-  VmSize:     1112 kB 
-  VmLck:         0 kB 
-  VmRSS:       348 kB 
-  VmData:       24 kB 
-  VmStk:        12 kB 
-  VmExe:         8 kB 
-  VmLib:      1044 kB 
-  SigPnd: 0000000000000000 
-  SigBlk: 0000000000000000 
-  SigIgn: 0000000000000000 
-  SigCgt: 0000000000000000 
-  CapInh: 00000000fffffeff 
-  CapPrm: 0000000000000000 
-  CapEff: 0000000000000000 
-
+  Uid:    501     501     501     501
+  Gid:    100     100     100     100
+  FDSize: 256
+  Groups: 100 14 16
+  VmPeak:     5004 kB
+  VmSize:     5004 kB
+  VmLck:         0 kB
+  VmHWM:       476 kB
+  VmRSS:       476 kB
+  VmData:      156 kB
+  VmStk:        88 kB
+  VmExe:        68 kB
+  VmLib:      1412 kB
+  VmPTE:        20 kb
+  Threads:        1
+  SigQ:   0/28578
+  SigPnd: 0000000000000000
+  ShdPnd: 0000000000000000
+  SigBlk: 0000000000000000
+  SigIgn: 0000000000000000
+  SigCgt: 0000000000000000
+  CapInh: 00000000fffffeff
+  CapPrm: 0000000000000000
+  CapEff: 0000000000000000
+  CapBnd: ffffffffffffffff
+  voluntary_ctxt_switches:        0
+  nonvoluntary_ctxt_switches:     1
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
-information. The  statm  file  contains  more  detailed  information about the
-process memory usage. Its seven fields are explained in Table 1-2.  The stat
-file contains details information about the process itself.  Its fields are
-explained in Table 1-3.
+information.  But you get a more detailed  view of the  process by reading the
+file /proc/PID/status. It fields are described in table 1-2.
 
+The  statm  file  contains  more  detailed  information about the process
+memory usage. Its seven fields are explained in Table 1-3.  The stat file
+contains details information about the process itself.  Its fields are
+explained in Table 1-4.
+
+Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+..............................................................................
+ Field                       Content
+ Name                        filename of the executable
+ State                       state (R is running, S is sleeping, D is sleeping
+                             in an uninterruptible wait, Z is zombie,
+			     T is traced or stopped)
+ Tgid                        thread group ID
+ Pid                         process id
+ PPid                        process id of the parent process
+ TracerPid                   PID of process tracing this process (0 if not)
+ Uid                         Real, effective, saved set, and  file system UIDs
+ Gid                         Real, effective, saved set, and  file system GIDs
+ FDSize                      number of file descriptor slots currently allocated
+ Groups                      supplementary group list
+ VmPeak                      peak virtual memory size
+ VmSize                      total program size
+ VmLck                       locked memory size
+ VmHWM                       peak resident set size ("high water mark")
+ VmRSS                       size of memory portions
+ VmData                      size of data, stack, and text segments
+ VmStk                       size of data, stack, and text segments
+ VmExe                       size of text segment
+ VmLib                       size of shared library code
+ VmPTE                       size of page table entries
+ Threads                     number of threads
+ SigQ                        number of signals queued/max. number for queue
+ SigPnd                      bitmap of pending signals for the thread
+ ShdPnd                      bitmap of shared pending signals for the process
+ SigBlk                      bitmap of blocked signals
+ SigIgn                      bitmap of ignored signals
+ SigCgt                      bitmap of catched signals
+ CapInh                      bitmap of inheritable capabilities
+ CapPrm                      bitmap of permitted capabilities
+ CapEff                      bitmap of effective capabilities
+ CapBnd                      bitmap of capabilities bounding set
+ Cpus_allowed                mask of CPUs on which this process may run
+ Cpus_allowed_list           Same as previous, but in "list format"
+ Mems_allowed                mask of memory nodes allowed to this process
+ Mems_allowed_list           Same as previous, but in "list format"
+ voluntary_ctxt_switches     number of voluntary context switches
+ nonvoluntary_ctxt_switches  number of non voluntary context switches
+..............................................................................
 
-Table 1-2: Contents of the statm files (as of 2.6.8-rc3)
+Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
 ..............................................................................
  Field    Content
  size     total program size (pages)		(same as VmSize in status)
@@ -188,7 +246,7 @@
 ..............................................................................
 
 
-Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
+Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
 ..............................................................................
  Field          Content
   pid           process id
@@ -222,10 +280,10 @@
   start_stack   address of the start of the stack
   esp           current value of ESP
   eip           current value of EIP
-  pending       bitmap of pending signals (obsolete)
-  blocked       bitmap of blocked signals (obsolete)
-  sigign        bitmap of ignored signals (obsolete)
-  sigcatch      bitmap of catched signals (obsolete)
+  pending       bitmap of pending signals
+  blocked       bitmap of blocked signals
+  sigign        bitmap of ignored signals
+  sigcatch      bitmap of catched signals
   wchan         address where process went to sleep
   0             (place holder)
   0             (place holder)
@@ -234,19 +292,99 @@
   rt_priority   realtime priority
   policy        scheduling policy (man sched_setscheduler)
   blkio_ticks   time spent waiting for block IO
+  gtime         guest time of the task in jiffies
+  cgtime        guest time of the task children in jiffies
 ..............................................................................
 
+The /proc/PID/map file containing the currently mapped memory regions and
+their access permissions.
+
+The format is:
+
+address           perms offset  dev   inode      pathname
+
+08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
+08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
+0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
+a7cb1000-a7cb2000 ---p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7eb2000-a7eb3000 ---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
+a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
+a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
+a800b000-a800e000 rw-p 00000000 00:00 0
+a800e000-a8022000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
+a8022000-a8023000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
+a8023000-a8024000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
+a8024000-a8027000 rw-p 00000000 00:00 0
+a8027000-a8043000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
+a8043000-a8044000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
+a8044000-a8045000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
+aff35000-aff4a000 rw-p 00000000 00:00 0          [stack]
+ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
+
+where "address" is the address space in the process that it occupies, "perms"
+is a set of permissions:
+
+ r = read
+ w = write
+ x = execute
+ s = shared
+ p = private (copy on write)
+
+"offset" is the offset into the mapping, "dev" is the device (major:minor), and
+"inode" is the inode  on that device.  0 indicates that  no inode is associated
+with the memory region, as the case would be with BSS (uninitialized data).
+The "pathname" shows the name associated file for this mapping.  If the mapping
+is not associated with a file:
+
+ [heap]                   = the heap of the program
+ [stack]                  = the stack of the main process
+ [vdso]                   = the "virtual dynamic shared object",
+                            the kernel system call handler
+
+ or if empty, the mapping is anonymous.
+
+
+The /proc/PID/smaps is an extension based on maps, showing the memory
+consumption for each of the process's mappings. For each of mappings there
+is a series of lines such as the following:
+
+08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash
+Size:               1084 kB
+Rss:                 892 kB
+Pss:                 374 kB
+Shared_Clean:        892 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:          892 kB
+Swap:                  0 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+
+The first  of these lines shows  the same information  as is displayed for the
+mapping in /proc/PID/maps.  The remaining lines show  the size of the mapping,
+the amount of the mapping that is currently resident in RAM, the "proportional
+set size” (divide each shared page by the number of processes sharing it), the
+number of clean and dirty shared pages in the mapping, and the number of clean
+and dirty private pages in the mapping.  The "Referenced" indicates the amount
+of memory currently marked as referenced or accessed.
+
+This file is only present if the CONFIG_MMU kernel configuration option is
+enabled.
 
 1.2 Kernel data
 ---------------
 
 Similar to  the  process entries, the kernel data files give information about
 the running kernel. The files used to obtain this information are contained in
-/proc and  are  listed  in Table 1-4. Not all of these will be present in your
+/proc and  are  listed  in Table 1-5. Not all of these will be present in your
 system. It  depends  on the kernel configuration and the loaded modules, which
 files are there, and which are missing.
 
-Table 1-4: Kernel info in /proc
+Table 1-5: Kernel info in /proc
 ..............................................................................
  File        Content                                           
  apm         Advanced power management info                    
@@ -614,10 +752,10 @@
 
 More detailed  information  can  be  found  in  the  controller  specific
 subdirectories. These  are  named  ide0,  ide1  and  so  on.  Each  of  these
-directories contains the files shown in table 1-5.
+directories contains the files shown in table 1-6.
 
 
-Table 1-5: IDE controller info in  /proc/ide/ide?
+Table 1-6: IDE controller info in  /proc/ide/ide?
 ..............................................................................
  File    Content                                 
  channel IDE channel (0 or 1)                    
@@ -627,11 +765,11 @@
 ..............................................................................
 
 Each device  connected  to  a  controller  has  a separate subdirectory in the
-controllers directory.  The  files  listed in table 1-6 are contained in these
+controllers directory.  The  files  listed in table 1-7 are contained in these
 directories.
 
 
-Table 1-6: IDE device information
+Table 1-7: IDE device information
 ..............................................................................
  File             Content                                    
  cache            The cache                                  
@@ -673,12 +811,12 @@
 1.4 Networking info in /proc/net
 --------------------------------
 
-The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-6 shows the
+The subdirectory  /proc/net  follows  the  usual  pattern. Table 1-8 shows the
 additional values  you  get  for  IP  version 6 if you configure the kernel to
-support this. Table 1-7 lists the files and their meaning.
+support this. Table 1-9 lists the files and their meaning.
 
 
-Table 1-6: IPv6 info in /proc/net 
+Table 1-8: IPv6 info in /proc/net 
 ..............................................................................
  File       Content                                               
  udp6       UDP sockets (IPv6)                                    
@@ -693,7 +831,7 @@
 ..............................................................................
 
 
-Table 1-7: Network info in /proc/net 
+Table 1-9: Network info in /proc/net 
 ..............................................................................
  File          Content                                                         
  arp           Kernel  ARP table                                               
@@ -817,10 +955,10 @@
 your system.  It  has  one  subdirectory  for  each port, named after the port
 number (0,1,2,...).
 
-These directories contain the four files shown in Table 1-8.
+These directories contain the four files shown in Table 1-10.
 
 
-Table 1-8: Files in /proc/parport 
+Table 1-10: Files in /proc/parport 
 ..............................................................................
  File      Content                                                             
  autoprobe Any IEEE-1284 device ID information that has been acquired.         
@@ -838,10 +976,10 @@
 
 Information about  the  available  and actually used tty's can be found in the
 directory /proc/tty.You'll  find  entries  for drivers and line disciplines in
-this directory, as shown in Table 1-9.
+this directory, as shown in Table 1-11.
 
 
-Table 1-9: Files in /proc/tty 
+Table 1-11: Files in /proc/tty 
 ..............................................................................
  File          Content                                        
  drivers       list of drivers and their usage                
@@ -926,9 +1064,9 @@
 /proc/fs/ext4.  Each mounted filesystem will have a directory in
 /proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
 /proc/fs/ext4/dm-0).   The files in each per-device directory are shown
-in Table 1-10, below.
+in Table 1-12, below.
 
-Table 1-10: Files in /proc/fs/ext4/<devname>
+Table 1-12: Files in /proc/fs/ext4/<devname>
 ..............................................................................
  File            Content                                        
  mb_groups       details of multiblock allocator buddy cache of free blocks


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 2/2] procfs: provide stack information for threads V0.7
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-10  6:46     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  6:46 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: a7f124b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - update Documentation/filesystem/proc.txt

The patch is against 2.6.30-rc7 and tested with 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.g
  - Fix missing mm->mmap_sem locking in function task_show_stack_usage()
  - Code cleanup
 
 Documentation/filesystems/proc.txt |    6 +++-
 linux-2.6.30/fs/exec.c             |    2 +
 linux-2.6.30/fs/proc/array.c       |   51 ++++++++++++++++++++++++++++++++++++-
 linux-2.6.30/fs/proc/task_mmu.c    |   14 ++++++++++
 linux-2.6.30/include/linux/sched.h |    1 
 linux-2.6.30/kernel/fork.c         |    2 +
 6 files changed, 74 insertions(+), 2 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 
--- linux-2.6.30.patch/Documentation/filesystems/proc.txt	2009-06-10 08:18:35.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-10 08:19:08.000000000 +0200
@@ -176,6 +176,7 @@
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -229,6 +230,7 @@
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -307,7 +309,7 @@
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: a7eb14b4]
 a7eb2000-a7eb3000 ---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
@@ -343,6 +345,8 @@
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the starting
+                            address of the stack
 
  or if empty, the mapping is anonymous.
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 2/2] procfs: provide stack information for threads V0.7
@ 2009-06-10  6:46     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  6:46 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the start address of the stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: a7f124b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - update Documentation/filesystem/proc.txt

The patch is against 2.6.30-rc7 and tested with 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.g
  - Fix missing mm->mmap_sem locking in function task_show_stack_usage()
  - Code cleanup
 
 Documentation/filesystems/proc.txt |    6 +++-
 linux-2.6.30/fs/exec.c             |    2 +
 linux-2.6.30/fs/proc/array.c       |   51 ++++++++++++++++++++++++++++++++++++-
 linux-2.6.30/fs/proc/task_mmu.c    |   14 ++++++++++
 linux-2.6.30/include/linux/sched.h |    1 
 linux-2.6.30/kernel/fork.c         |    2 +
 6 files changed, 74 insertions(+), 2 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-04 22:10:47.000000000 +0200
@@ -242,6 +242,20 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+						 stack_start);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 
--- linux-2.6.30.patch/Documentation/filesystems/proc.txt	2009-06-10 08:18:35.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-10 08:19:08.000000000 +0200
@@ -176,6 +176,7 @@
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -229,6 +230,7 @@
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -307,7 +309,7 @@
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: a7eb14b4]
 a7eb2000-a7eb3000 ---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
@@ -343,6 +345,8 @@
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the starting
+                            address of the stack
 
  or if empty, the mapping is anonymous.
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 2/2] procfs: provide stack information for threads V0.8
  2009-04-01 19:31   ` Ingo Molnar
@ 2009-06-10  7:20     ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  7:20 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the maximum size of stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - change maps/smaps output, displays now the max. stack size

The patch is against 2.6.30-rc7 and tested with 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
 
 Documentation/filesystems/proc.txt |    5 ++-
 fs/exec.c                          |    2 +
 fs/proc/array.c                    |   51 ++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c                 |   19 +++++++++++++
 include/linux/sched.h              |    1 
 kernel/fork.c                      |    2 +
 6 files changed, 78 insertions(+), 2 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/Documentation/filesystems/proc.txt linux-2.6.30/Documentation/filesystems/proc.txt
--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-10 09:09:27.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-10 09:07:46.000000000 +0200
@@ -176,6 +176,7 @@
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -229,6 +230,7 @@
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -307,7 +309,7 @@
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
 a7eb2000-a7eb3000 ---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
@@ -343,6 +345,7 @@
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-10 09:02:40.000000000 +0200
@@ -242,6 +242,25 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+#ifdef CONFIG_STACK_GROWSUP
+						 vma->vm_end - stack_start
+#else
+						 stack_start - vma->vm_start
+#endif
+						);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [patch 2/2] procfs: provide stack information for threads V0.8
@ 2009-06-10  7:20     ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-10  7:20 UTC (permalink / raw)
  To: linux-kernel, linux-mm; +Cc: Andrew Morton

This is the newest version of the formaly named "detailed stack info"
patch which give you a better overview of the userland application stack
usage, especially for embedded linux.

Currently you are only able to dump the main process/thread stack usage
which is showed in /proc/pid/status by the "VmStk" Value. But you get no
information about the consumed stack memory of the the threads.

There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
marks the vm mapping where the thread stack pointer reside with "[thread
stack xxxxxxxx]". xxxxxxxx is the maximum size of stack. This is a
value information, because libpthread doesn't set the start of the stack
to the top of the mapped area, depending of the pthread usage.

A sample output of /proc/<pid>/task/<tid>/maps looks like:

08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7d12000-a7d13000 ---p 00000000 00:00 0 
a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
a7f13000-a7f14000 ---p 00000000 00:00 0 
a7f14000-a7f36000 rw-p 00000000 00:00 0 
a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a806c000-a806f000 rw-p 00000000 00:00 0 
a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8085000-a8088000 rw-p 00000000 00:00 0 
a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

 
Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
which will you give the current stack usage in kb.

A sample output of /proc/self/status looks like:

Name:	cat
State:	R (running)
Tgid:	507
Pid:	507
.
.
.
CapBnd:	fffffffffffffeff
voluntary_ctxt_switches:	0
nonvoluntary_ctxt_switches:	0
Stack usage:	12 kB

I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
base address of the associated thread stack and not the one of the main
process. This makes more sense.

Changes since last posting:

 - change maps/smaps output, displays now the max. stack size

The patch is against 2.6.30-rc7 and tested with 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
 
 Documentation/filesystems/proc.txt |    5 ++-
 fs/exec.c                          |    2 +
 fs/proc/array.c                    |   51 ++++++++++++++++++++++++++++++++++++-
 fs/proc/task_mmu.c                 |   19 +++++++++++++
 include/linux/sched.h              |    1 
 kernel/fork.c                      |    2 +
 6 files changed, 78 insertions(+), 2 deletions(-)

Signed-off-by: Stefani Seibold <stefani@seibold.net>

diff -u -N -r linux-2.6.30.orig/Documentation/filesystems/proc.txt linux-2.6.30/Documentation/filesystems/proc.txt
--- linux-2.6.30.orig/Documentation/filesystems/proc.txt	2009-06-10 09:09:27.000000000 +0200
+++ linux-2.6.30/Documentation/filesystems/proc.txt	2009-06-10 09:07:46.000000000 +0200
@@ -176,6 +176,7 @@
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -229,6 +230,7 @@
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -307,7 +309,7 @@
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
 a7eb2000-a7eb3000 ---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
@@ -343,6 +345,7 @@
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [thread stack, xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
diff -u -N -r linux-2.6.30.orig/fs/exec.c linux-2.6.30/fs/exec.c
--- linux-2.6.30.orig/fs/exec.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/exec.c	2009-06-04 09:32:35.000000000 +0200
@@ -1328,6 +1328,8 @@
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
diff -u -N -r linux-2.6.30.orig/fs/proc/array.c linux-2.6.30/fs/proc/array.c
--- linux-2.6.30.orig/fs/proc/array.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/array.c	2009-06-05 21:13:30.000000000 +0200
@@ -321,6 +321,54 @@
 			p->nivcsw);
 }
 
+static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma,
+					struct task_struct *p)
+{
+	unsigned long	i;
+	struct page	*page;
+	unsigned long	stkpage;
+
+	stkpage = KSTK_ESP(p) & PAGE_MASK;
+
+#ifdef CONFIG_STACK_GROWSUP
+	for (i = vma->vm_end; i-PAGE_SIZE > stkpage; i -= PAGE_SIZE) {
+
+		page = follow_page(vma, i-PAGE_SIZE, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return i - (p->stack_start & PAGE_MASK);
+#else
+	for (i = vma->vm_start; i+PAGE_SIZE <= stkpage; i += PAGE_SIZE) {
+
+		page = follow_page(vma, i, 0);
+
+		if (!IS_ERR(page) && page)
+			break;
+	}
+	return (p->stack_start & PAGE_MASK) - i + PAGE_SIZE;
+#endif
+}
+
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *task)
+{
+	struct vm_area_struct	*vma;
+	struct mm_struct	*mm = get_task_mm(task);
+
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, task->stack_start);
+		if (vma)
+			seq_printf(m, "Stack usage:\t%lu kB\n",
+				get_stack_usage_in_bytes(vma, task) >> 10);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -340,6 +388,7 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+	task_show_stack_usage(m, task);
 	return 0;
 }
 
@@ -481,7 +530,7 @@
 		rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
-		(permitted && mm) ? mm->start_stack : 0,
+		(permitted) ? task->stack_start : 0,
 		esp,
 		eip,
 		/* The signal information here is obsolete.
diff -u -N -r linux-2.6.30.orig/fs/proc/task_mmu.c linux-2.6.30/fs/proc/task_mmu.c
--- linux-2.6.30.orig/fs/proc/task_mmu.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/fs/proc/task_mmu.c	2009-06-10 09:02:40.000000000 +0200
@@ -242,6 +242,25 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+				} else {
+					unsigned long stack_start;
+					struct proc_maps_private *pmp;
+
+					pmp = m->private;
+					stack_start = pmp->task->stack_start;
+
+					if (vma->vm_start <= stack_start &&
+					    vma->vm_end >= stack_start) {
+						pad_len_spaces(m, len);
+						seq_printf(m,
+						 "[thread stack: %08lx]",
+#ifdef CONFIG_STACK_GROWSUP
+						 vma->vm_end - stack_start
+#else
+						 stack_start - vma->vm_start
+#endif
+						);
+					}
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.30.orig/include/linux/sched.h linux-2.6.30/include/linux/sched.h
--- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
@@ -1429,6 +1429,7 @@
 	/* state flags for use by tracers */
 	unsigned long trace;
 #endif
+	unsigned long stack_start;
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -u -N -r linux-2.6.30.orig/kernel/fork.c linux-2.6.30/kernel/fork.c
--- linux-2.6.30.orig/kernel/fork.c	2009-06-04 09:29:47.000000000 +0200
+++ linux-2.6.30/kernel/fork.c	2009-06-04 13:15:35.000000000 +0200
@@ -1092,6 +1092,8 @@
 	if (unlikely(current->ptrace))
 		ptrace_fork(p, clone_flags);
 
+	p->stack_start = stack_start;
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch 2/2] procfs: provide stack information for threads V0.8
  2009-06-10  7:20     ` Stefani Seibold
@ 2009-06-15 22:01       ` Andrew Morton
  -1 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-15 22:01 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Ingo Molnar

On Wed, 10 Jun 2009 09:20:41 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the maximum size of stack. This is a
> value information, because libpthread doesn't set the start of the stack
> to the top of the mapped area, depending of the pthread usage.
> 
> A sample output of /proc/<pid>/task/<tid>/maps looks like:
> 
> 08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
> 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
> 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
> a7d12000-a7d13000 ---p 00000000 00:00 0 
> a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
> a7f13000-a7f14000 ---p 00000000 00:00 0 
> a7f14000-a7f36000 rw-p 00000000 00:00 0 
> a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
> a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
> a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
> a806c000-a806f000 rw-p 00000000 00:00 0 
> a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
> a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
> a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
> a8085000-a8088000 rw-p 00000000 00:00 0 
> a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
> a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
> a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
> afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
> ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
> 
>  
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> A sample output of /proc/self/status looks like:
> 
> Name:	cat
> State:	R (running)
> Tgid:	507
> Pid:	507
> .
> .
> .
> CapBnd:	fffffffffffffeff
> voluntary_ctxt_switches:	0
> nonvoluntary_ctxt_switches:	0
> Stack usage:	12 kB
> 
> I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
> base address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
>
> ...
>
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  

A `stack_start' in the task_struct.  This is a bit confusing - we
already have a `void *stack' in there.  Perhaps this should be named
user_stack_start or something?



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch 2/2] procfs: provide stack information for threads V0.8
@ 2009-06-15 22:01       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2009-06-15 22:01 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Ingo Molnar

On Wed, 10 Jun 2009 09:20:41 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
> 
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
> 
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the maximum size of stack. This is a
> value information, because libpthread doesn't set the start of the stack
> to the top of the mapped area, depending of the pthread usage.
> 
> A sample output of /proc/<pid>/task/<tid>/maps looks like:
> 
> 08048000-08049000 r-xp 00000000 03:00 8312       /opt/z
> 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/z
> 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
> a7d12000-a7d13000 ---p 00000000 00:00 0 
> a7d13000-a7f13000 rw-p 00000000 00:00 0          [thread stack: 001ff4b4]
> a7f13000-a7f14000 ---p 00000000 00:00 0 
> a7f14000-a7f36000 rw-p 00000000 00:00 0 
> a7f36000-a8069000 r-xp 00000000 03:00 4222       /lib/libc.so.6
> a8069000-a806b000 r--p 00133000 03:00 4222       /lib/libc.so.6
> a806b000-a806c000 rw-p 00135000 03:00 4222       /lib/libc.so.6
> a806c000-a806f000 rw-p 00000000 00:00 0 
> a806f000-a8083000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
> a8083000-a8084000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
> a8084000-a8085000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
> a8085000-a8088000 rw-p 00000000 00:00 0 
> a8088000-a80a4000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
> a80a4000-a80a5000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
> a80a5000-a80a6000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
> afaf5000-afb0a000 rw-p 00000000 00:00 0          [stack]
> ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
> 
>  
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
> 
> A sample output of /proc/self/status looks like:
> 
> Name:	cat
> State:	R (running)
> Tgid:	507
> Pid:	507
> .
> .
> .
> CapBnd:	fffffffffffffeff
> voluntary_ctxt_switches:	0
> nonvoluntary_ctxt_switches:	0
> Stack usage:	12 kB
> 
> I also fixed stack base address in /proc/<pid>/{task/*,}/stat to the
> base address of the associated thread stack and not the one of the main
> process. This makes more sense.
> 
>
> ...
>
> --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> @@ -1429,6 +1429,7 @@
>  	/* state flags for use by tracers */
>  	unsigned long trace;
>  #endif
> +	unsigned long stack_start;
>  };
>  

A `stack_start' in the task_struct.  This is a bit confusing - we
already have a `void *stack' in there.  Perhaps this should be named
user_stack_start or something?


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch 2/2] procfs: provide stack information for threads V0.8
  2009-06-15 22:01       ` Andrew Morton
@ 2009-06-16  7:14         ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-16  7:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm, Ingo Molnar

Am Montag, den 15.06.2009, 15:01 -0700 schrieb Andrew Morton:
> > ...
> >
> > --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> > +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> > @@ -1429,6 +1429,7 @@
> >  	/* state flags for use by tracers */
> >  	unsigned long trace;
> >  #endif
> > +	unsigned long stack_start;
> >  };
> >  
> 
> A `stack_start' in the task_struct.  This is a bit confusing - we
> already have a `void *stack' in there.  Perhaps this should be named
> user_stack_start or something?
> 
> 
IMHO i think the void *stack is also a to general name, it should be
name kernel_stack or thread_info.

In real we have two stack, so the name user_stack and kernel_stack would
be my favor.

I have examined the source and and task_struct void *stack would be used
in about 10 files.
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch 2/2] procfs: provide stack information for threads V0.8
@ 2009-06-16  7:14         ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-06-16  7:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-mm, Ingo Molnar

Am Montag, den 15.06.2009, 15:01 -0700 schrieb Andrew Morton:
> > ...
> >
> > --- linux-2.6.30.orig/include/linux/sched.h	2009-06-04 09:29:47.000000000 +0200
> > +++ linux-2.6.30/include/linux/sched.h	2009-06-04 09:32:35.000000000 +0200
> > @@ -1429,6 +1429,7 @@
> >  	/* state flags for use by tracers */
> >  	unsigned long trace;
> >  #endif
> > +	unsigned long stack_start;
> >  };
> >  
> 
> A `stack_start' in the task_struct.  This is a bit confusing - we
> already have a `void *stack' in there.  Perhaps this should be named
> user_stack_start or something?
> 
> 
IMHO i think the void *stack is also a to general name, it should be
name kernel_stack or thread_info.

In real we have two stack, so the name user_stack and kernel_stack would
be my favor.

I have examined the source and and task_struct void *stack would be used
in about 10 files.
 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-06-04 20:21     ` Stefani Seibold
@ 2009-10-02 21:17       ` Andreas Schwab
  -1 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-02 21:17 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

Stefani Seibold <stefani@seibold.net> writes:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
>
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
>
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
>
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
>
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.

That does not work right.  I sometimes get meaningless values printed
for the stack usage in /proc/*/status (like 18014398509480456 kB), and
the stack start in /proc/*/stat is wrong.  Apparently task->stack_start
contains the stack start of the _parent_ process.

$ awk '{printf "%x\n", $28}' /proc/self/stat; grep stack /proc/self/maps /proc/$$/maps
ffd34990
/proc/self/maps:ffa9c000-ffab1000 rw-p 00000000 00:00 0                                  [stack]
/proc/4054/maps:ffd22000-ffd37000 rw-p 00000000 00:00 0                                  [stack]

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-10-02 21:17       ` Andreas Schwab
  0 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-02 21:17 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

Stefani Seibold <stefani@seibold.net> writes:

> This is the newest version of the formaly named "detailed stack info"
> patch which give you a better overview of the userland application stack
> usage, especially for embedded linux.
>
> Currently you are only able to dump the main process/thread stack usage
> which is showed in /proc/pid/status by the "VmStk" Value. But you get no
> information about the consumed stack memory of the the threads.
>
> There is an enhancement in the /proc/<pid>/{task/*,}/*maps and which
> marks the vm mapping where the thread stack pointer reside with "[thread
> stack xxxxxxxx]". xxxxxxxx is the start address of the stack.
>
> Also there is a new entry "stack usage" in /proc/<pid>/{task/*,}/status
> which will you give the current stack usage in kb.
>
> I also fixed stack base address in /proc/<pid>/task/*/stat to the base
> address of the associated thread stack and not the one of the main
> process. This makes more sense.

That does not work right.  I sometimes get meaningless values printed
for the stack usage in /proc/*/status (like 18014398509480456 kB), and
the stack start in /proc/*/stat is wrong.  Apparently task->stack_start
contains the stack start of the _parent_ process.

$ awk '{printf "%x\n", $28}' /proc/self/stat; grep stack /proc/self/maps /proc/$$/maps
ffd34990
/proc/self/maps:ffa9c000-ffab1000 rw-p 00000000 00:00 0                                  [stack]
/proc/4054/maps:ffd22000-ffd37000 rw-p 00000000 00:00 0                                  [stack]

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-10-02 21:17       ` Andreas Schwab
@ 2009-10-02 21:44         ` Andreas Schwab
  -1 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-02 21:44 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

That missed compat_do_execve.

Andreas.

>From 2e81a4ab8da611f340a536aaaccbb274bfa0de5c Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@linux-m68k.org>
Date: Fri, 2 Oct 2009 23:43:47 +0200
Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve

---
 fs/compat.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/fs/compat.c b/fs/compat.c
index d576b55..6c19040 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
-- 
1.6.4.4


-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-10-02 21:44         ` Andreas Schwab
  0 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-02 21:44 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

That missed compat_do_execve.

Andreas.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-10-02 21:44         ` Andreas Schwab
@ 2009-10-03  6:47           ` Andreas Schwab
  -1 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-03  6:47 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

Here's the patch again properly signed.

Andreas.

>From 9da252fd7d9a5cf84a477a35a6b52f927c85b280 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@linux-m68k.org>
Date: Sat, 3 Oct 2009 08:19:43 +0200
Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
---
 fs/compat.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/fs/compat.c b/fs/compat.c
index d576b55..6c19040 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
 	if (retval < 0)
 		goto out;
 
+	current->stack_start = current->mm->start_stack;
+
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
-- 
1.6.4.4


-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-10-03  6:47           ` Andreas Schwab
  0 siblings, 0 replies; 57+ messages in thread
From: Andreas Schwab @ 2009-10-03  6:47 UTC (permalink / raw)
  To: Stefani Seibold; +Cc: linux-kernel, linux-mm, Andrew Morton

Here's the patch again properly signed.

Andreas.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-10-03  6:47           ` Andreas Schwab
@ 2009-10-03  7:40             ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-10-03  7:40 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-kernel, linux-mm, Andrew Morton

Sorry, i missed this. Good job ;-)

Stefani

Am Samstag, den 03.10.2009, 08:47 +0200 schrieb Andreas Schwab:
> Here's the patch again properly signed.
> 
> Andreas.
> 
> >From 9da252fd7d9a5cf84a477a35a6b52f927c85b280 Mon Sep 17 00:00:00 2001
> From: Andreas Schwab <schwab@linux-m68k.org>
> Date: Sat, 3 Oct 2009 08:19:43 +0200
> Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve
> 
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> ---
>  fs/compat.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/compat.c b/fs/compat.c
> index d576b55..6c19040 100644
> --- a/fs/compat.c
> +++ b/fs/compat.c
> @@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> -- 
> 1.6.4.4
> 
> 


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-10-03  7:40             ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-10-03  7:40 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-kernel, linux-mm, Andrew Morton

Sorry, i missed this. Good job ;-)

Stefani

Am Samstag, den 03.10.2009, 08:47 +0200 schrieb Andreas Schwab:
> Here's the patch again properly signed.
> 
> Andreas.
> 
> >From 9da252fd7d9a5cf84a477a35a6b52f927c85b280 Mon Sep 17 00:00:00 2001
> From: Andreas Schwab <schwab@linux-m68k.org>
> Date: Sat, 3 Oct 2009 08:19:43 +0200
> Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve
> 
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> ---
>  fs/compat.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/compat.c b/fs/compat.c
> index d576b55..6c19040 100644
> --- a/fs/compat.c
> +++ b/fs/compat.c
> @@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> -- 
> 1.6.4.4
> 
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
  2009-10-03  6:47           ` Andreas Schwab
@ 2009-10-03 11:33             ` Stefani Seibold
  -1 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-10-03 11:33 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-kernel, linux-mm, Andrew Morton

Sorry, i missed this. Good job ;-)

Am Samstag, den 03.10.2009, 08:47 +0200 schrieb Andreas Schwab: 
> Here's the patch again properly signed.
> 
> Andreas.
> 
> >From 9da252fd7d9a5cf84a477a35a6b52f927c85b280 Mon Sep 17 00:00:00 2001
> From: Andreas Schwab <schwab@linux-m68k.org>
> Date: Sat, 3 Oct 2009 08:19:43 +0200
> Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve
> 
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> ---
>  fs/compat.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/compat.c b/fs/compat.c
> index d576b55..6c19040 100644
> --- a/fs/compat.c
> +++ b/fs/compat.c
> @@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> -- 
> 1.6.4.4
> 
> 


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [patch] procfs: provide stack information for threads
@ 2009-10-03 11:33             ` Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-10-03 11:33 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-kernel, linux-mm, Andrew Morton

Sorry, i missed this. Good job ;-)

Am Samstag, den 03.10.2009, 08:47 +0200 schrieb Andreas Schwab: 
> Here's the patch again properly signed.
> 
> Andreas.
> 
> >From 9da252fd7d9a5cf84a477a35a6b52f927c85b280 Mon Sep 17 00:00:00 2001
> From: Andreas Schwab <schwab@linux-m68k.org>
> Date: Sat, 3 Oct 2009 08:19:43 +0200
> Subject: [PATCH] compat_do_execve: set current->stack_start as in do_execve
> 
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> ---
>  fs/compat.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/compat.c b/fs/compat.c
> index d576b55..6c19040 100644
> --- a/fs/compat.c
> +++ b/fs/compat.c
> @@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
>  	if (retval < 0)
>  		goto out;
>  
> +	current->stack_start = current->mm->start_stack;
> +
>  	/* execve succeeded */
>  	current->fs->in_exec = 0;
>  	current->in_execve = 0;
> -- 
> 1.6.4.4
> 
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Detailed Stack Information Patch [1/3]
@ 2009-01-20 10:16 Stefani Seibold
  0 siblings, 0 replies; 57+ messages in thread
From: Stefani Seibold @ 2009-01-20 10:16 UTC (permalink / raw)
  To: linux-kernel

diff -u -N -r linux-2.6.28.1.orig/fs/exec.c linux-2.6.28.1/fs/exec.c
--- linux-2.6.28.1.orig/fs/exec.c	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/fs/exec.c	2009-01-20 09:10:35.000000000 +0100
@@ -1342,6 +1342,9 @@
 	current->flags &= ~PF_KTHREAD;
 	retval = search_binary_handler(bprm,regs);
 	if (retval >= 0) {
+#ifdef CONFIG_PROC_STACK
+		current->stack_start = current->mm->start_stack;
+#endif
 		/* execve success */
 		security_bprm_free(bprm);
 		acct_update_integrals(current);
diff -u -N -r linux-2.6.28.1.orig/fs/proc/array.c linux-2.6.28.1/fs/proc/array.c
--- linux-2.6.28.1.orig/fs/proc/array.c	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/fs/proc/array.c	2009-01-20 09:10:35.000000000 +0100
@@ -308,6 +308,25 @@
 			p->nivcsw);
 }
 
+#ifdef CONFIG_PROC_STACK
+static inline void task_show_stack_usage(struct seq_file *m,
+						struct task_struct *p)
+{
+	unsigned long		cur_stack;
+	unsigned long		base_page;
+
+	base_page = KSTK_ESP(p) >> PAGE_SHIFT;
+
+#ifdef CONFIG_STACK_GROWSUP
+	cur_stack = base_page-(p->stack_start >> PAGE_SHIFT);
+#else
+	cur_stack = (p->stack_start >> PAGE_SHIFT)-base_page;
+#endif
+	seq_printf(m,	"stack usage:\t%lu kB\n",
+		(cur_stack + 1) << (PAGE_SHIFT-10));
+}
+#endif
+
 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -327,6 +346,9 @@
 	task_show_regs(m, task);
 #endif
 	task_context_switch_counts(m, task);
+#ifdef CONFIG_PROC_STACK
+	task_show_stack_usage(m, task);
+#endif
 	return 0;
 }
 
diff -u -N -r linux-2.6.28.1.orig/fs/proc/task_mmu.c linux-2.6.28.1/fs/proc/task_mmu.c
--- linux-2.6.28.1.orig/fs/proc/task_mmu.c	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/fs/proc/task_mmu.c	2009-01-20 09:10:35.000000000 +0100
@@ -240,6 +240,11 @@
 				} else if (vma->vm_start <= mm->start_stack &&
 					   vma->vm_end >= mm->start_stack) {
 					name = "[stack]";
+#ifdef CONFIG_PROC_STACK
+				} else if (vma->vm_start <= mm->start_stack &&
+					   vma->vm_end >= mm->start_stack) {
+					name = "[thread stack]";
+#endif
 				}
 			} else {
 				name = "[vdso]";
diff -u -N -r linux-2.6.28.1.orig/include/linux/sched.h linux-2.6.28.1/include/linux/sched.h
--- linux-2.6.28.1.orig/include/linux/sched.h	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/include/linux/sched.h	2009-01-20 09:10:35.000000000 +0100
@@ -1356,6 +1356,9 @@
 	unsigned long default_timer_slack_ns;
 
 	struct list_head	*scm_work_list;
+#ifdef CONFIG_PROC_STACK
+	unsigned long stack_start;
+#endif
 };
 
 /*
diff -u -N -r linux-2.6.28.1.orig/init/Kconfig linux-2.6.28.1/init/Kconfig
--- linux-2.6.28.1.orig/init/Kconfig	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/init/Kconfig	2009-01-20 09:10:36.000000000 +0100
@@ -814,6 +814,18 @@
 
 source "arch/Kconfig"
 
+config PROC_STACK
+ 	default y
+	depends on PROC_FS && MMU
+	bool "Enable /proc/<pid> stack monitoring" if EMBEDDED
+ 	help
+	  This enables monitoring of process and thread stack utilization.
+
+	  The /proc/pid/maps, /proc/pid/smaps, /proc/pid/status and the
+	  /proc/pid/task/pid pedants will be extended by the stack information.
+	  Disabling these interfaces will reduce the size of the kernel by
+	  approximately 1kb.
+
 endmenu		# General setup
 
 config HAVE_GENERIC_DMA_COHERENT
diff -u -N -r linux-2.6.28.1.orig/kernel/fork.c linux-2.6.28.1/kernel/fork.c
--- linux-2.6.28.1.orig/kernel/fork.c	2009-01-18 19:45:37.000000000 +0100
+++ linux-2.6.28.1/kernel/fork.c	2009-01-20 09:10:36.000000000 +0100
@@ -1093,6 +1093,11 @@
 	p->blocked_on = NULL; /* not blocked yet */
 #endif
 
+#ifdef CONFIG_PROC_STACK
+	p->stack_start = (stack_start == KSTK_ESP(current)) ?
+		current->stack_start : stack_start;
+#endif
+
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 



^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2009-10-03 11:33 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-31 14:58 Detailed Stack Information Patch [1/3] Stefani Seibold
2009-03-31 14:58 ` Stefani Seibold
2009-04-01 19:31 ` Ingo Molnar
2009-04-01 19:31   ` Ingo Molnar
2009-04-02 21:26   ` Stefani Seibold
2009-04-02 21:26     ` Stefani Seibold
2009-06-03 20:34   ` Detailed Stack Information Patch Next Generation Stefani Seibold
2009-06-03 20:34     ` Stefani Seibold
2009-06-03 21:06     ` Andrew Morton
2009-06-03 21:06       ` Andrew Morton
2009-06-04 11:23   ` [patch] procfs: provide stack information for threads Stefani Seibold
2009-06-04 11:23     ` Stefani Seibold
2009-06-04 11:37     ` Andrew Morton
2009-06-04 11:37       ` Andrew Morton
2009-06-04 11:56       ` Stefani Seibold
2009-06-04 11:56         ` Stefani Seibold
2009-06-04 17:57         ` Andrew Morton
2009-06-04 17:57           ` Andrew Morton
2009-06-04 20:21   ` Stefani Seibold
2009-06-04 20:21     ` Stefani Seibold
2009-06-04 21:23     ` Andrew Morton
2009-06-04 21:23       ` Andrew Morton
2009-06-05 19:12       ` Stefani Seibold
2009-06-05 19:12         ` Stefani Seibold
2009-06-05 19:19         ` Andrew Morton
2009-06-05 19:19           ` Andrew Morton
2009-10-02 21:17     ` Andreas Schwab
2009-10-02 21:17       ` Andreas Schwab
2009-10-02 21:44       ` Andreas Schwab
2009-10-02 21:44         ` Andreas Schwab
2009-10-03  6:47         ` Andreas Schwab
2009-10-03  6:47           ` Andreas Schwab
2009-10-03  7:40           ` Stefani Seibold
2009-10-03  7:40             ` Stefani Seibold
2009-10-03 11:33           ` Stefani Seibold
2009-10-03 11:33             ` Stefani Seibold
2009-06-06 10:01   ` [patch] procfs: provide stack information for threads V0.6 Stefani Seibold
2009-06-06 10:01     ` Stefani Seibold
2009-06-09 10:35   ` [patch] proc.txt: Update kernel filesystem/proc.txt documentation Stefani Seibold
2009-06-09 10:35     ` Stefani Seibold
2009-06-09 19:36     ` Andrew Morton
2009-06-09 19:36       ` Andrew Morton
2009-06-09 20:53       ` Stefani Seibold
2009-06-09 20:53         ` Stefani Seibold
2009-06-09 21:13         ` Andrew Morton
2009-06-09 21:13           ` Andrew Morton
2009-06-10  6:46   ` [patch 1/2] " Stefani Seibold
2009-06-10  6:46     ` Stefani Seibold
2009-06-10  6:46   ` [patch 2/2] procfs: provide stack information for threads V0.7 Stefani Seibold
2009-06-10  6:46     ` Stefani Seibold
2009-06-10  7:20   ` [patch 2/2] procfs: provide stack information for threads V0.8 Stefani Seibold
2009-06-10  7:20     ` Stefani Seibold
2009-06-15 22:01     ` Andrew Morton
2009-06-15 22:01       ` Andrew Morton
2009-06-16  7:14       ` Stefani Seibold
2009-06-16  7:14         ` Stefani Seibold
  -- strict thread matches above, loose matches on Subject: below --
2009-01-20 10:16 Detailed Stack Information Patch [1/3] Stefani Seibold

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.