-mm/linux-next: procfs: Mark thread stack correctly in proc/<pid>/maps
Subsystems (6)
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Andrew Morton
maintainerQuoted 1 line · On Tue, 13 Mar 2012 23:04:36 +0530 Siddhesh Poyarekar…
Following is the updated patch with requested changes incorporated.
Boy, that's a lot of changes (below). What does it all do?
Why did the sched.h inclusions get taken out again?
Documentation/filesystems/proc.txt | 36 +++++++++++++--- fs/proc/task_mmu.c | 59 ++++++++++++++++++--------- fs/proc/task_nommu.c | 11 ++++- mm/memory.c | 38 ----------------- mm/nommu.c | 40 ------------------ mm/util.c | 41 ++++++++++++++++++ 6 files changed, 121 insertions(+), 104 deletions(-)
Documentation/filesystems/proc.txt renamed from Documentation/filesystems/proc.txt~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +29 -7
@@ -325,7 +325,7 @@ address perms offset dev in 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 +a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack:1001] 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
@@ -337,7 +337,7 @@ 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:1001] +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"
@@ -356,8 +356,8 @@ The "pathname" shows the name associated is not associated with a file: [heap] = the heap of the program - [stack:1001] = the mapping is used as a stack by the thread - with tid 1001 + [stack] = the stack of the main process + [stack:1001] = the stack of the thread with tid 1001 [vdso] = the "virtual dynamic shared object", the kernel system call handler
@@ -365,9 +365,31 @@ is not associated with a file: The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint of the individual tasks of a process. In this file you will see a mapping marked -as [stack:TID] only if that task sees it as a stack. This is a key difference -from the content of /proc/PID/maps, where you will see all mappings that are -being used as stack by all of those tasks. +as [stack] if that task sees it as a stack. This is a key difference from the +content of /proc/PID/maps, where you will see all mappings that are being used +as stack by all of those tasks. Hence, for the example above, the task-level +map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: + +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 [stack] +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 +ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso] 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
fs/proc/task_mmu.c renamed from fs/proc/task_mmu.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +41 -18
89 lines not on this page · raw message
fs/proc/task_nommu.c renamed from fs/proc/task_nommu.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +10 -1
@@ -171,9 +171,18 @@ static int nommu_vma_show(struct seq_filseq_path (m, &file->f_path,"" ); }else if (mm) {pid_t tid =vm_is_stack (priv->task, vma, is_pid); +if (tid !=0 ) {pad_len_spaces (m, len); -seq_printf (m,"[stack:%d]" , tid); +/* +* Thread stack in /proc/PID/task/TID/maps or +* the main process stack. +*/ +if (!is_pid || (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack)) +seq_printf (m,"[stack]" ); +else +seq_printf (m,"[stack:%d]" , tid); } }
mm/memory.c renamed from mm/memory.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +0 -38
@@ -57,7 +57,6 @@#include <linux/swapops.h> #include <linux/elf.h> #include <linux/gfp.h> -#include <linux/sched.h> #include <asm/io.h> #include <asm/pgalloc.h>
@@ -113,13 +112,6 @@ __setup("norandmaps", disable_randmaps);unsigned long zero_pfn__read_mostly ;unsigned long highest_memmap_pfn__read_mostly ; -/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task (struct task_struct *t, -struct vm_area_struct *vma) -{ -return (vma->vm_start <=KSTK_ESP (t) && vma->vm_end >=KSTK_ESP (t)); -} -/* * CONFIG_MMU architectures set up ZERO_PAGE in their paging_init() */
@@ -3899,36 +3891,6 @@ void print_vma_addr(char *prefix, unsignup_read (¤t->mm->mmap_sem); } -/* -* Check if the vma is being used as a stack. -* If is_group is non-zero, check in the entire thread group or else -* just check in the current task. Returns the pid of the task that -* the vma is stack for. -*/ -pid_t vm_is_stack (struct task_struct *task, -struct vm_area_struct *vma,int in_group) -{ -pid_t ret =0 ; - -if (vm_is_stack_for_task (task, vma)) -return task->pid; - -if (in_group) { -struct task_struct *t = task; -rcu_read_lock (); - while_each_thread(task, t) { -if (vm_is_stack_for_task (t, vma)) { - ret = t->pid; - goto done; - } - } - } - -done: -rcu_read_unlock (); -return ret; -} -#ifdef CONFIG_PROVE_LOCKING void might_fault (void ) {
mm/nommu.c renamed from mm/nommu.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +0 -40
@@ -29,7 +29,6 @@#include <linux/security.h> #include <linux/syscalls.h> #include <linux/audit.h> -#include <linux/sched.h> #include <asm/uaccess.h> #include <asm/tlb.h>
@@ -2095,42 +2094,3 @@ int nommu_shrink_inode_mappings(struct iup_write (&nommu_region_sem);return 0 ; } - -/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task (struct task_struct *t, -struct vm_area_struct *vma) -{ -return (vma->vm_start <=KSTK_ESP (t) && vma->vm_end >=KSTK_ESP (t)); -} - -/* -* Check if the vma is being used as a stack. -* If is_group is non-zero, check in the entire thread group or else -* just check in the current task. Returns the pid of the task that -* the vma is stack for. -*/ -pid_t vm_is_stack(struct task_struct *task, - struct vm_area_struct *vma, int in_group) -{ - pid_t ret = 0; - - if (vm_is_stack_for_task(task, vma)) - return task->pid; - - if (in_group) { - struct task_struct *t; - rcu_read_lock(); - t = list_first_entry_rcu(&task->thread_group, - struct task_struct, thread_group); - do { - if (vm_is_stack_for_task(t, vma)) { - ret = t->pid; - goto done; - } - } while_each_thread(task, t); -done: - rcu_read_unlock(); - } - - return ret; -}
mm/util.c renamed from mm/util.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +41 -0
47 lines not on this page · raw message
_
Quoted 4 lines · Andrew Morton
Boy, that's a lot of changes (below). What does it all do?
Why did the
sched.hinclusions get taken out again?
Most of it is code shuffling in addition to the feature change I mentioned earlier. I've elaborated on the changes inline.
Quoted 3 lines
diff -puN
Documentation/filesystems/proc.txt~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3Documentation/filesystems/proc.txtDocumentation/filesystems/proc.txt renamed from Documentation/filesystems/proc.txt~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +0
-0
<snip>
Quoted 21 lines
The
/proc/PID/task/TID/mapsis a view of the virtual memory from the viewpoint of the individual tasks of a process. In this file you will see a mapping markedDocumentation/filesystems/proc.txt renamed from Documentation/filesystems/proc.txt~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +15
-3-as [stack:TID] only if that task sees it as a stack. This is a key difference -from the content of /proc/PID/maps, where you will see all mappings that are -being used as stack by all of those tasks. +as [stack] if that task sees it as a stack. This is a key difference from the +content of /proc/PID/maps, where you will see all mappings that are being used +as stack by all of those tasks. Hence, for the example above, the task-level +map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: + +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 [stack] +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
Documentation/filesystems/proc.txt is not associated with a file: · line 392
Quoted 10 lines
Documentation/filesystems/proc.txt renamed from Documentation/filesystems/proc.txt~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +10
-0+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 +ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
I extended the documentation a bit to give an example of how /proc/PID/task/TID/maps would look like. This reflects the feature change that KOSAKI-san requested (keeping process stack as [stack] in /proc/PID/maps).
Quoted 82 lines
fs/proc/task_mmu.c renamed from fs/proc/task_mmu.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +32
-18@@ -222,7 +222,7 @@ show_map_vma(struct seq_file *m, struct unsigned long start, end; dev_t dev = 0; int len; - const char *name; + const char *name = NULL; if (file) { struct inode *inode = vma->vm_file->f_path.dentry->d_inode;@@ -256,33 +256,47 @@ show_map_vma(struct seq_file *m, struct if (file) { pad_len_spaces(m, len); seq_path(m, &file->f_path, "\n"); - goto out; + goto done; } name = arch_vma_name(vma); if (!name) { - if (mm) { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - name = "[heap]"; - } else { - pid_t tid; + pid_t tid; - tid = vm_is_stack(task, vma, is_pid); - if (tid != 0) { - pad_len_spaces(m, len); - seq_printf(m, "[stack:%d]", tid); - } - } - } else { + if (!mm) { name = "[vdso]"; + goto done; + } + + if (vma->vm_start <= mm->brk && + vma->vm_end >= mm->start_brk) { + name = "[heap]"; + goto done; + } + + tid = vm_is_stack(task, vma, is_pid); + + if (tid !=0) { + /* + * Thread stack in /proc/PID/task/TID/maps or + * the main process stack. + */ + if (!is_pid || (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack)) { + name = "[stack]"; + } else { + /* Thread stack in /proc/PID/maps */ + pad_len_spaces(m, len); + seq_printf(m, "[stack:%d]", tid); + } } } + +done: if (name) { pad_len_spaces(m, len); seq_puts(m, name); } -out: seq_putc(m, '\n'); }@@ -1134,8 +1148,17 @@ static int show_numa_map(struct seq_file seq_printf(m, " heap"); } else { pid_t tid = vm_is_stack(proc_priv->task, vma, is_pid); - if (tid != 0) - seq_printf(m, " stack:%d", tid); + if (tid !=0) { + /*
fs/proc/task_mmu.c static int show_numa_map(struct seq_file · line 1162
Quoted 10 lines
fs/proc/task_mmu.c renamed from fs/proc/task_mmu.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +9
-0+* Thread stack in /proc/PID/task/TID/maps or +* the main process stack. +*/ + if (!is_pid || (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack)) + seq_printf(m, " stack"); + else + seq_printf(m, " stack:%d", tid); + } }
The request to keep process stack marked as [stack] meant an additional nested condition, so I cleaned up the code like you had suggested earlier.
Quoted 51 lines
diff -puN
mm/util.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3mm/util.cmm/util.c renamed from mm/util.c~procfs-mark-thread-stack-correctly-in-proc-pid-maps-v3 +41
-0@@ -239,6 +239,47 @@ void __vma_link_list(struct mm_struct *m next->vm_prev = vma; } +/* Check if the vma is being used as a stack by this task */ +static int vm_is_stack_for_task (struct task_struct *t, + struct vm_area_struct *vma) +{ + return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); +} + +/* +* Check if the vma is being used as a stack. +* If is_group is non-zero, check in the entire thread group or else +* just check in the current task. Returns the pid of the task that +* the vma is stack for. +*/ +pid_t vm_is_stack(struct task_struct *task, + struct vm_area_struct *vma, int in_group) +{ + pid_t ret = 0; + + if (vm_is_stack_for_task(task, vma)) + return task->pid; + + if (in_group) { + struct task_struct *t; + rcu_read_lock(); + if (!pid_alive(task)) + goto done; + + t = task; + do { + if (vm_is_stack_for_task(t, vma)) { + ret = t->pid; + goto done; + } + } while_each_thread(task, t); +done: + rcu_read_unlock(); + } + + return ret; +} + #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT) void arch_pick_mmap_layout(struct mm_struct *mm) {
Quoted 2 lines
_
I had duplicated the vm_is_stack functions for mmu and nommu in memory.c and nommu.c, which I unified and moved to util.c (above), which is built in both mmu and nommu and also seemed like a good enough place for it since it is a utility function. util.c already includes sched.h, which is why the sched.h inclusions are not needed anymore.
I forgot to mention how I have tested this:
* Build and functionality test on x86_64
* Build test for i386
* Build test for nommu with a bit of a hack; removing mmu code in x86 and building it as if it were nommu.
Signature · 2 lines
Siddhesh Poyarekar http://siddhesh.in
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Tue, 13 Mar 2012 23:04:36 +0530 Siddhesh Poyarekar…
Following is the updated patch with requested changes incorporated.
Boy, that's a lot of changes (below). What does it all do?
Hi,
Since this patch was included in the -mm tree on March 14th, I assumed that linux-next would get the patch in today's merge, but it hasn't. Is there something I am missing? Does the patch need additional review/acks that I need to request for?
Thanks,
Siddhesh
Thanks,
Siddhesh
Signature · 2 lines
Siddhesh Poyarekar http://siddhesh.in
Quoted 10 lines · Siddhesh Poyarekar
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Tue, 13 Mar 2012 23:04:36 +0530 Siddhesh Poyarekar…
Following is the updated patch with requested changes incorporated.
Boy, that's a lot of changes (below). What does it all do?
Quoted 6 lines
Hi,
Since this patch was included in the -mm tree on March 14th, I assumed that linux-next would get the patch in today's merge, but it hasn't. Is there something I am missing? Does the patch need additional review/acks that I need to request for?
Hi Siddhesh,
It looks like this still fails. The original failure was:
super.c:(.text+0x3ffd8): undefined reference to `vm_is_stack'
Now it is:
mm/nommu.o: In function `vm_is_stack':
nommu.c:(.text+0x2178): multiple definition of `vm_is_stack' mm/util.o:util.c:(.text+0x2bc): first defined here make[2]: *** [mm/built-in.o] Error 1
http://kisskb.ellerman.id.au/kisskb/buildresult/5941188/
Can you include in your testing for v3, the ARM at91x40_defconfig please?
Thanks,
Paul.
Quoted 15 lines
Thanks,
SiddheshThanks,
Siddhesh--
Siddhesh Poyarekar
http://siddhesh.in
--
To unsubscribe from this list: send the line "unsubscribe linux-next" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 8 lines · Paul Gortmaker
Now it is:
mm/nommu.o: In function `vm_is_stack':
nommu.c:(.text+0x2178): multiple definition of `vm_is_stack' mm/util.o:util.c:(.text+0x2bc): first defined here make[2]: *** [mm/built-in.o] Error 1
Looks like the problem is because this patch got included in linux-next 2 days ago:
When I had consolidated all of these changes into what Andrew got the v3 patch from, this patch should have been removed since I moved this function definition from memory.c and nommu.c into util.c, but it looks like the patch got merged in once again, causing the build error above. Dropping this patch should be sufficient to fix the build problem. This is also the reason why the March 22 build was successful (with my final changes) and the March 24 build wasn't (with this additional patch).
Signature · 2 lines
Siddhesh Poyarekar http://siddhesh.in
Hi Siddhesh,
Quoted 10 lines · On Mon, 26 Mar 2012 08:32:35 +0530 Siddhesh Poyarekar…
Quoted 7 lines · Paul Gortmaker
Now it is:
mm/nommu.o: In function `vm_is_stack':
nommu.c:(.text+0x2178): multiple definition of `vm_is_stack' mm/util.o:util.c:(.text+0x2bc): first defined here make[2]: *** [mm/built-in.o] Error 1
Quoted 6 lines
Looks like the problem is because this patch got included in linux-next 2 days ago:
I will remove that patch today.
Signature · 3 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/