diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2012-03-23 18:02:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:42 -0400 |
commit | 59a32e2ce5eb809967cac4e718bc527beca83c59 (patch) | |
tree | 3024b71063f497c138680c36c5f7ce2dee563680 /fs/proc/stat.c | |
parent | b908243c549448fc0662f9cdd8d5cfe620fcdc31 (diff) |
proc: speed up /proc/stat handling
On a typical 16 cpus machine, "cat /proc/stat" gives more than 4096 bytes,
and is slow :
# strace -T -o /tmp/STRACE cat /proc/stat | wc -c
5826
# grep "cpu " /tmp/STRACE
read(0, "cpu 1949310 19 2144714 12117253"..., 32768) = 5826 <0.001504>
Thats partly because show_stat() must be called twice since initial
buffer size is too small (4096 bytes for less than 32 possible cpus)
Fix this by :
1) Taking into account nr_irqs in the initial buffer sizing.
2) Using ksize() to allow better filling of initial buffer.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Paul Turner <pjt@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/stat.c')
-rw-r--r-- | fs/proc/stat.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 121f77cfef76..ac446114cd48 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -157,11 +157,14 @@ static int show_stat(struct seq_file *p, void *v) | |||
157 | 157 | ||
158 | static int stat_open(struct inode *inode, struct file *file) | 158 | static int stat_open(struct inode *inode, struct file *file) |
159 | { | 159 | { |
160 | unsigned size = 4096 * (1 + num_possible_cpus() / 32); | 160 | unsigned size = 1024 + 128 * num_possible_cpus(); |
161 | char *buf; | 161 | char *buf; |
162 | struct seq_file *m; | 162 | struct seq_file *m; |
163 | int res; | 163 | int res; |
164 | 164 | ||
165 | /* minimum size to display an interrupt count : 2 bytes */ | ||
166 | size += 2 * nr_irqs; | ||
167 | |||
165 | /* don't ask for more than the kmalloc() max size */ | 168 | /* don't ask for more than the kmalloc() max size */ |
166 | if (size > KMALLOC_MAX_SIZE) | 169 | if (size > KMALLOC_MAX_SIZE) |
167 | size = KMALLOC_MAX_SIZE; | 170 | size = KMALLOC_MAX_SIZE; |
@@ -173,7 +176,7 @@ static int stat_open(struct inode *inode, struct file *file) | |||
173 | if (!res) { | 176 | if (!res) { |
174 | m = file->private_data; | 177 | m = file->private_data; |
175 | m->buf = buf; | 178 | m->buf = buf; |
176 | m->size = size; | 179 | m->size = ksize(buf); |
177 | } else | 180 | } else |
178 | kfree(buf); | 181 | kfree(buf); |
179 | return res; | 182 | return res; |