diff options
author | Mauricio Lin <mauriciolin@gmail.com> | 2005-09-03 18:55:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:05:49 -0400 |
commit | e070ad49f31155d872d8e96cab2142840993e3c0 (patch) | |
tree | 16d5bfd3d7627d6616c6b1008fac80e4cf77379e /fs/proc/base.c | |
parent | 00e145b6d59a16dd7740197a18f7abdb3af004a9 (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.c | 61 |
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 | ||
585 | extern struct seq_operations proc_pid_smaps_op; | ||
586 | static 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 | |||
597 | static struct file_operations proc_smaps_operations = { | ||
598 | .open = smaps_open, | ||
599 | .read = seq_read, | ||
600 | .llseek = seq_lseek, | ||
601 | .release = seq_release, | ||
602 | }; | ||
603 | |||
547 | extern struct seq_operations mounts_op; | 604 | extern struct seq_operations mounts_op; |
548 | static int mounts_open(struct inode *inode, struct file *file) | 605 | static 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; |