• Siddhesh Poyarekar's avatar
    procfs: mark thread stack correctly in proc/<pid>/maps · b7643757
    Siddhesh Poyarekar authored
    Stack for a new thread is mapped by userspace code and passed via
    sys_clone.  This memory is currently seen as anonymous in
    /proc/<pid>/maps, which makes it difficult to ascertain which mappings
    are being used for thread stacks.  This patch uses the individual task
    stack pointers to determine which vmas are actually thread stacks.
    
    For a multithreaded program like the following:
    
    	#include <pthread.h>
    
    	void *thread_main(void *foo)
    	{
    		while(1);
    	}
    
    	int main()
    	{
    		pthread_t t;
    		pthread_create(&t, NULL, thread_main, NULL);
    		pthread_join(t, NULL);
    	}
    
    proc/PID/maps looks like the following:
    
        00400000-00401000 r-xp 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        00600000-00601000 rw-p 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        019ef000-01a10000 rw-p 00000000 00:00 0                                  [heap]
        7f8a44491000-7f8a44492000 ---p 00000000 00:00 0
        7f8a44492000-7f8a44c92000 rw-p 00000000 00:00 0
        7f8a44c92000-7f8a44e3d000 r-xp 00000000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a44e3d000-7f8a4503d000 ---p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a4503d000-7f8a45041000 r--p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45041000-7f8a45043000 rw-p 001af000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45043000-7f8a45048000 rw-p 00000000 00:00 0
        7f8a45048000-7f8a4505f000 r-xp 00000000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4505f000-7f8a4525e000 ---p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525e000-7f8a4525f000 r--p 00016000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525f000-7f8a45260000 rw-p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a45260000-7f8a45264000 rw-p 00000000 00:00 0
        7f8a45264000-7f8a45286000 r-xp 00000000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45457000-7f8a4545a000 rw-p 00000000 00:00 0
        7f8a45484000-7f8a45485000 rw-p 00000000 00:00 0
        7f8a45485000-7f8a45486000 r--p 00021000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45486000-7f8a45487000 rw-p 00022000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45487000-7f8a45488000 rw-p 00000000 00:00 0
        7fff6273b000-7fff6275c000 rw-p 00000000 00:00 0                          [stack]
        7fff627ff000-7fff62800000 r-xp 00000000 00:00 0                          [vdso]
        ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    
    Here, one could guess that 7f8a44492000-7f8a44c92000 is a stack since
    the earlier vma that has no permissions (7f8a44e3d000-7f8a4503d000) but
    that is not always a reliable way to find out which vma is a thread
    stack.  Also, /proc/PID/maps and /proc/PID/task/TID/maps has the same
    content.
    
    With this patch in place, /proc/PID/task/TID/maps are treated as 'maps
    as the task would see it' and hence, only the vma that that task uses as
    stack is marked as [stack].  All other 'stack' vmas are marked as
    anonymous memory.  /proc/PID/maps acts as a thread group level view,
    where all thread stack vmas are marked as [stack:TID] where TID is the
    process ID of the task that uses that vma as stack, while the process
    stack is marked as [stack].
    
    So /proc/PID/maps will look like this:
    
        00400000-00401000 r-xp 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        00600000-00601000 rw-p 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        019ef000-01a10000 rw-p 00000000 00:00 0                                  [heap]
        7f8a44491000-7f8a44492000 ---p 00000000 00:00 0
        7f8a44492000-7f8a44c92000 rw-p 00000000 00:00 0                          [stack:1442]
        7f8a44c92000-7f8a44e3d000 r-xp 00000000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a44e3d000-7f8a4503d000 ---p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a4503d000-7f8a45041000 r--p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45041000-7f8a45043000 rw-p 001af000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45043000-7f8a45048000 rw-p 00000000 00:00 0
        7f8a45048000-7f8a4505f000 r-xp 00000000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4505f000-7f8a4525e000 ---p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525e000-7f8a4525f000 r--p 00016000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525f000-7f8a45260000 rw-p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a45260000-7f8a45264000 rw-p 00000000 00:00 0
        7f8a45264000-7f8a45286000 r-xp 00000000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45457000-7f8a4545a000 rw-p 00000000 00:00 0
        7f8a45484000-7f8a45485000 rw-p 00000000 00:00 0
        7f8a45485000-7f8a45486000 r--p 00021000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45486000-7f8a45487000 rw-p 00022000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45487000-7f8a45488000 rw-p 00000000 00:00 0
        7fff6273b000-7fff6275c000 rw-p 00000000 00:00 0                          [stack]
        7fff627ff000-7fff62800000 r-xp 00000000 00:00 0                          [vdso]
        ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    
    Thus marking all vmas that are used as stacks by the threads in the
    thread group along with the process stack.  The task level maps will
    however like this:
    
        00400000-00401000 r-xp 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        00600000-00601000 rw-p 00000000 fd:0a 3671804                            /home/siddhesh/a.out
        019ef000-01a10000 rw-p 00000000 00:00 0                                  [heap]
        7f8a44491000-7f8a44492000 ---p 00000000 00:00 0
        7f8a44492000-7f8a44c92000 rw-p 00000000 00:00 0                          [stack]
        7f8a44c92000-7f8a44e3d000 r-xp 00000000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a44e3d000-7f8a4503d000 ---p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a4503d000-7f8a45041000 r--p 001ab000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45041000-7f8a45043000 rw-p 001af000 fd:00 2097482                    /lib64/libc-2.14.90.so
        7f8a45043000-7f8a45048000 rw-p 00000000 00:00 0
        7f8a45048000-7f8a4505f000 r-xp 00000000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4505f000-7f8a4525e000 ---p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525e000-7f8a4525f000 r--p 00016000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a4525f000-7f8a45260000 rw-p 00017000 fd:00 2099938                    /lib64/libpthread-2.14.90.so
        7f8a45260000-7f8a45264000 rw-p 00000000 00:00 0
        7f8a45264000-7f8a45286000 r-xp 00000000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45457000-7f8a4545a000 rw-p 00000000 00:00 0
        7f8a45484000-7f8a45485000 rw-p 00000000 00:00 0
        7f8a45485000-7f8a45486000 r--p 00021000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45486000-7f8a45487000 rw-p 00022000 fd:00 2097348                    /lib64/ld-2.14.90.so
        7f8a45487000-7f8a45488000 rw-p 00000000 00:00 0
        7fff6273b000-7fff6275c000 rw-p 00000000 00:00 0
        7fff627ff000-7fff62800000 r-xp 00000000 00:00 0                          [vdso]
        ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    
    where only the vma that is being used as a stack by *that* task is
    marked as [stack].
    
    Analogous changes have been made to /proc/PID/smaps,
    /proc/PID/numa_maps, /proc/PID/task/TID/smaps and
    /proc/PID/task/TID/numa_maps. Relevant snippets from smaps and
    numa_maps:
    
        [siddhesh@localhost ~ ]$ pgrep a.out
        1441
        [siddhesh@localhost ~ ]$ cat /proc/1441/smaps | grep "\[stack"
        7f8a44492000-7f8a44c92000 rw-p 00000000 00:00 0                          [stack:1442]
        7fff6273b000-7fff6275c000 rw-p 00000000 00:00 0                          [stack]
        [siddhesh@localhost ~ ]$ cat /proc/1441/task/1442/smaps | grep "\[stack"
        7f8a44492000-7f8a44c92000 rw-p 00000000 00:00 0                          [stack]
        [siddhesh@localhost ~ ]$ cat /proc/1441/task/1441/smaps | grep "\[stack"
        7fff6273b000-7fff6275c000 rw-p 00000000 00:00 0                          [stack]
        [siddhesh@localhost ~ ]$ cat /proc/1441/numa_maps | grep "stack"
        7f8a44492000 default stack:1442 anon=2 dirty=2 N0=2
        7fff6273a000 default stack anon=3 dirty=3 N0=3
        [siddhesh@localhost ~ ]$ cat /proc/1441/task/1442/numa_maps | grep "stack"
        7f8a44492000 default stack anon=2 dirty=2 N0=2
        [siddhesh@localhost ~ ]$ cat /proc/1441/task/1441/numa_maps | grep "stack"
        7fff6273a000 default stack anon=3 dirty=3 N0=3
    
    [akpm@linux-foundation.org: checkpatch fixes]
    [akpm@linux-foundation.org: fix build]
    Signed-off-by: default avatarSiddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
    Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: Jamie Lokier <jamie@shareable.org>
    Cc: Mike Frysinger <vapier@gentoo.org>
    Cc: Alexey Dobriyan <adobriyan@gmail.com>
    Cc: Matt Mackall <mpm@selenic.com>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b7643757
internal.h 4.96 KB