aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorMauricio Lin <mauriciolin@gmail.com>2005-09-03 18:55:10 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:05:49 -0400
commite070ad49f31155d872d8e96cab2142840993e3c0 (patch)
tree16d5bfd3d7627d6616c6b1008fac80e4cf77379e /fs/proc/base.c
parent00e145b6d59a16dd7740197a18f7abdb3af004a9 (diff)
[PATCH] add /proc/pid/smaps
Add a "smaps" entry to /proc/pid: show howmuch memory is resident in each mapping. People that want to perform a memory consumption analysing can use it mainly if someone needs to figure out which libraries can be reduced for embedded systems. So the new features are the physical size of shared and clean [or dirty]; private and clean [or dirty]. Take a look the example below: # cat /proc/4576/smaps 08048000-080dc000 r-xp /bin/bash Size: 592 KB Rss: 500 KB Shared_Clean: 500 KB Shared_Dirty: 0 KB Private_Clean: 0 KB Private_Dirty: 0 KB 080dc000-080e2000 rw-p /bin/bash Size: 24 KB Rss: 24 KB Shared_Clean: 0 KB Shared_Dirty: 0 KB Private_Clean: 0 KB Private_Dirty: 24 KB 080e2000-08116000 rw-p Size: 208 KB Rss: 208 KB Shared_Clean: 0 KB Shared_Dirty: 0 KB Private_Clean: 0 KB Private_Dirty: 208 KB b7e2b000-b7e34000 r-xp /lib/tls/libnss_files-2.3.2.so Size: 36 KB Rss: 12 KB Shared_Clean: 12 KB Shared_Dirty: 0 KB Private_Clean: 0 KB Private_Dirty: 0 KB ... (Includes a cleanup from "Richard Purdie" <rpurdie@rpsys.net>) From: Torsten Foertsch <torsten.foertsch@gmx.net> show_smap calls first show_map and then prints its additional information to the seq_file. show_map checks if all it has to print fits into the buffer and if yes marks the current vma as written. While that is correct for show_map it is not for show_smap. Here the vma should be marked as written only after the additional information is also written. The attached patch cures the problem. It moves the functionality of the show_map function to a new function show_map_internal that is called with an additional struct mem_size_stats* argument. Then show_map calls show_map_internal with NULL as struct mem_size_stats* whereas show_smap calls it with a real pointer. Now the final if (m->count < m->size) /* vma is copied successfully */ m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; is done only if the whole entry fits into the buffer. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b796bf90a0b1..520978e49e92 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -11,6 +11,40 @@
11 * go into icache. We cache the reference to task_struct upon lookup too. 11 * go into icache. We cache the reference to task_struct upon lookup too.
12 * Eventually it should become a filesystem in its own. We don't use the 12 * Eventually it should become a filesystem in its own. We don't use the
13 * rest of procfs anymore. 13 * rest of procfs anymore.
14 *
15 *
16 * Changelog:
17 * 17-Jan-2005
18 * Allan Bezerra
19 * Bruna Moreira <bruna.moreira@indt.org.br>
20 * Edjard Mota <edjard.mota@indt.org.br>
21 * Ilias Biris <ilias.biris@indt.org.br>
22 * Mauricio Lin <mauricio.lin@indt.org.br>
23 *
24 * Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
25 *
26 * A new process specific entry (smaps) included in /proc. It shows the
27 * size of rss for each memory area. The maps entry lacks information
28 * about physical memory size (rss) for each mapped file, i.e.,
29 * rss information for executables and library files.
30 * This additional information is useful for any tools that need to know
31 * about physical memory consumption for a process specific library.
32 *
33 * Changelog:
34 * 21-Feb-2005
35 * Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
36 * Pud inclusion in the page table walking.
37 *
38 * ChangeLog:
39 * 10-Mar-2005
40 * 10LE Instituto Nokia de Tecnologia - INdT:
41 * A better way to walks through the page table as suggested by Hugh Dickins.
42 *
43 * Simo Piiroinen <simo.piiroinen@nokia.com>:
44 * Smaps information related to shared, private, clean and dirty pages.
45 *
46 * Paul Mundt <paul.mundt@nokia.com>:
47 * Overall revision about smaps.
14 */ 48 */
15 49
16#include <asm/uaccess.h> 50#include <asm/uaccess.h>
@@ -68,6 +102,7 @@ enum pid_directory_inos {
68 PROC_TGID_NUMA_MAPS, 102 PROC_TGID_NUMA_MAPS,
69 PROC_TGID_MOUNTS, 103 PROC_TGID_MOUNTS,
70 PROC_TGID_WCHAN, 104 PROC_TGID_WCHAN,
105 PROC_TGID_SMAPS,
71#ifdef CONFIG_SCHEDSTATS 106#ifdef CONFIG_SCHEDSTATS
72 PROC_TGID_SCHEDSTAT, 107 PROC_TGID_SCHEDSTAT,
73#endif 108#endif
@@ -106,6 +141,7 @@ enum pid_directory_inos {
106 PROC_TID_NUMA_MAPS, 141 PROC_TID_NUMA_MAPS,
107 PROC_TID_MOUNTS, 142 PROC_TID_MOUNTS,
108 PROC_TID_WCHAN, 143 PROC_TID_WCHAN,
144 PROC_TID_SMAPS,
109#ifdef CONFIG_SCHEDSTATS 145#ifdef CONFIG_SCHEDSTATS
110 PROC_TID_SCHEDSTAT, 146 PROC_TID_SCHEDSTAT,
111#endif 147#endif
@@ -157,6 +193,7 @@ static struct pid_entry tgid_base_stuff[] = {
157 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), 193 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
158 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), 194 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
159 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), 195 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
196 E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
160#ifdef CONFIG_SECURITY 197#ifdef CONFIG_SECURITY
161 E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), 198 E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
162#endif 199#endif
@@ -196,6 +233,7 @@ static struct pid_entry tid_base_stuff[] = {
196 E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), 233 E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
197 E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), 234 E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
198 E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), 235 E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
236 E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
199#ifdef CONFIG_SECURITY 237#ifdef CONFIG_SECURITY
200 E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), 238 E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
201#endif 239#endif
@@ -544,6 +582,25 @@ static struct file_operations proc_numa_maps_operations = {
544}; 582};
545#endif 583#endif
546 584
585extern struct seq_operations proc_pid_smaps_op;
586static int smaps_open(struct inode *inode, struct file *file)
587{
588 struct task_struct *task = proc_task(inode);
589 int ret = seq_open(file, &proc_pid_smaps_op);
590 if (!ret) {
591 struct seq_file *m = file->private_data;
592 m->private = task;
593 }
594 return ret;
595}
596
597static struct file_operations proc_smaps_operations = {
598 .open = smaps_open,
599 .read = seq_read,
600 .llseek = seq_lseek,
601 .release = seq_release,
602};
603
547extern struct seq_operations mounts_op; 604extern struct seq_operations mounts_op;
548static int mounts_open(struct inode *inode, struct file *file) 605static int mounts_open(struct inode *inode, struct file *file)
549{ 606{
@@ -1574,6 +1631,10 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1574 case PROC_TGID_MOUNTS: 1631 case PROC_TGID_MOUNTS:
1575 inode->i_fop = &proc_mounts_operations; 1632 inode->i_fop = &proc_mounts_operations;
1576 break; 1633 break;
1634 case PROC_TID_SMAPS:
1635 case PROC_TGID_SMAPS:
1636 inode->i_fop = &proc_smaps_operations;
1637 break;
1577#ifdef CONFIG_SECURITY 1638#ifdef CONFIG_SECURITY
1578 case PROC_TID_ATTR: 1639 case PROC_TID_ATTR:
1579 inode->i_nlink = 2; 1640 inode->i_nlink = 2;