aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2016-10-07 20:02:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:30 -0400
commitf7a5f132b447cb6301ab3f0b0468a63db29e41f5 (patch)
treea164515c5507cd32f548bd8f9ab559dee6a508fa /fs/proc
parent68ba0326b4e14988f9e0c24a6e12a85cf2acd1ca (diff)
proc: faster /proc/*/status
top(1) opens the following files for every PID: /proc/*/stat /proc/*/statm /proc/*/status This patch switches /proc/*/status away from seq_printf(). The result is 13.5% speedup. Benchmark is open("/proc/self/status")+read+close 1.000.000 million times. BEFORE $ perf stat -r 10 taskset -c 3 ./proc-self-status Performance counter stats for 'taskset -c 3 ./proc-self-status' (10 runs): 10748.474301 task-clock (msec) # 0.954 CPUs utilized ( +- 0.91% ) 12 context-switches # 0.001 K/sec ( +- 1.09% ) 1 cpu-migrations # 0.000 K/sec 104 page-faults # 0.010 K/sec ( +- 0.45% ) 37,424,127,876 cycles # 3.482 GHz ( +- 0.04% ) 8,453,010,029 stalled-cycles-frontend # 22.59% frontend cycles idle ( +- 0.12% ) 3,747,609,427 stalled-cycles-backend # 10.01% backend cycles idle ( +- 0.68% ) 65,632,764,147 instructions # 1.75 insn per cycle # 0.13 stalled cycles per insn ( +- 0.00% ) 13,981,324,775 branches # 1300.773 M/sec ( +- 0.00% ) 138,967,110 branch-misses # 0.99% of all branches ( +- 0.18% ) 11.263885428 seconds time elapsed ( +- 0.04% ) ^^^^^^^^^^^^ AFTER $ perf stat -r 10 taskset -c 3 ./proc-self-status Performance counter stats for 'taskset -c 3 ./proc-self-status' (10 runs): 9010.521776 task-clock (msec) # 0.925 CPUs utilized ( +- 1.54% ) 11 context-switches # 0.001 K/sec ( +- 1.54% ) 1 cpu-migrations # 0.000 K/sec ( +- 11.11% ) 103 page-faults # 0.011 K/sec ( +- 0.60% ) 32,352,310,603 cycles # 3.591 GHz ( +- 0.07% ) 7,849,199,578 stalled-cycles-frontend # 24.26% frontend cycles idle ( +- 0.27% ) 3,269,738,842 stalled-cycles-backend # 10.11% backend cycles idle ( +- 0.73% ) 56,012,163,567 instructions # 1.73 insn per cycle # 0.14 stalled cycles per insn ( +- 0.00% ) 11,735,778,795 branches # 1302.453 M/sec ( +- 0.00% ) 98,084,459 branch-misses # 0.84% of all branches ( +- 0.28% ) 9.741247736 seconds time elapsed ( +- 0.07% ) ^^^^^^^^^^^ Link: http://lkml.kernel.org/r/20160806125608.GB1187@p183.telecom.by Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Joe Perches <joe@perches.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 88c7de12197b..5e7d2521d496 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -186,51 +186,52 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
186 task_unlock(p); 186 task_unlock(p);
187 rcu_read_unlock(); 187 rcu_read_unlock();
188 188
189 seq_printf(m, 189 seq_printf(m, "State:\t%s", get_task_state(p));
190 "State:\t%s\n" 190
191 "Tgid:\t%d\n" 191 seq_puts(m, "\nTgid:\t");
192 "Ngid:\t%d\n" 192 seq_put_decimal_ull(m, 0, tgid);
193 "Pid:\t%d\n" 193 seq_puts(m, "\nNgid:\t");
194 "PPid:\t%d\n" 194 seq_put_decimal_ull(m, 0, ngid);
195 "TracerPid:\t%d\n" 195 seq_puts(m, "\nPid:\t");
196 "Uid:\t%d\t%d\t%d\t%d\n" 196 seq_put_decimal_ull(m, 0, pid_nr_ns(pid, ns));
197 "Gid:\t%d\t%d\t%d\t%d\n" 197 seq_puts(m, "\nPPid:\t");
198 "FDSize:\t%d\nGroups:\t", 198 seq_put_decimal_ull(m, 0, ppid);
199 get_task_state(p), 199 seq_puts(m, "\nTracerPid:\t");
200 tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid, 200 seq_put_decimal_ull(m, 0, tpid);
201 from_kuid_munged(user_ns, cred->uid), 201 seq_puts(m, "\nUid:");
202 from_kuid_munged(user_ns, cred->euid), 202 seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->uid));
203 from_kuid_munged(user_ns, cred->suid), 203 seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->euid));
204 from_kuid_munged(user_ns, cred->fsuid), 204 seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->suid));
205 from_kgid_munged(user_ns, cred->gid), 205 seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->fsuid));
206 from_kgid_munged(user_ns, cred->egid), 206 seq_puts(m, "\nGid:");
207 from_kgid_munged(user_ns, cred->sgid), 207 seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->gid));
208 from_kgid_munged(user_ns, cred->fsgid), 208 seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->egid));
209 max_fds); 209 seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->sgid));
210 210 seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->fsgid));
211 seq_puts(m, "\nFDSize:\t");
212 seq_put_decimal_ull(m, 0, max_fds);
213
214 seq_puts(m, "\nGroups:\t");
211 group_info = cred->group_info; 215 group_info = cred->group_info;
212 for (g = 0; g < group_info->ngroups; g++) 216 for (g = 0; g < group_info->ngroups; g++)
213 seq_printf(m, "%d ", 217 seq_put_decimal_ull(m, g ? ' ' : 0, from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
214 from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
215 put_cred(cred); 218 put_cred(cred);
219 /* Trailing space shouldn't have been added in the first place. */
220 seq_putc(m, ' ');
216 221
217#ifdef CONFIG_PID_NS 222#ifdef CONFIG_PID_NS
218 seq_puts(m, "\nNStgid:"); 223 seq_puts(m, "\nNStgid:");
219 for (g = ns->level; g <= pid->level; g++) 224 for (g = ns->level; g <= pid->level; g++)
220 seq_printf(m, "\t%d", 225 seq_put_decimal_ull(m, '\t', task_tgid_nr_ns(p, pid->numbers[g].ns));
221 task_tgid_nr_ns(p, pid->numbers[g].ns));
222 seq_puts(m, "\nNSpid:"); 226 seq_puts(m, "\nNSpid:");
223 for (g = ns->level; g <= pid->level; g++) 227 for (g = ns->level; g <= pid->level; g++)
224 seq_printf(m, "\t%d", 228 seq_put_decimal_ull(m, '\t', task_pid_nr_ns(p, pid->numbers[g].ns));
225 task_pid_nr_ns(p, pid->numbers[g].ns));
226 seq_puts(m, "\nNSpgid:"); 229 seq_puts(m, "\nNSpgid:");
227 for (g = ns->level; g <= pid->level; g++) 230 for (g = ns->level; g <= pid->level; g++)
228 seq_printf(m, "\t%d", 231 seq_put_decimal_ull(m, '\t', task_pgrp_nr_ns(p, pid->numbers[g].ns));
229 task_pgrp_nr_ns(p, pid->numbers[g].ns));
230 seq_puts(m, "\nNSsid:"); 232 seq_puts(m, "\nNSsid:");
231 for (g = ns->level; g <= pid->level; g++) 233 for (g = ns->level; g <= pid->level; g++)
232 seq_printf(m, "\t%d", 234 seq_put_decimal_ull(m, '\t', task_session_nr_ns(p, pid->numbers[g].ns));
233 task_session_nr_ns(p, pid->numbers[g].ns));
234#endif 235#endif
235 seq_putc(m, '\n'); 236 seq_putc(m, '\n');
236} 237}
@@ -299,11 +300,14 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
299 unlock_task_sighand(p, &flags); 300 unlock_task_sighand(p, &flags);
300 } 301 }
301 302
302 seq_printf(m, "Threads:\t%d\n", num_threads); 303 seq_puts(m, "Threads:\t");
303 seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim); 304 seq_put_decimal_ull(m, 0, num_threads);
305 seq_puts(m, "\nSigQ:\t");
306 seq_put_decimal_ull(m, 0, qsize);
307 seq_put_decimal_ull(m, '/', qlim);
304 308
305 /* render them all */ 309 /* render them all */
306 render_sigset_t(m, "SigPnd:\t", &pending); 310 render_sigset_t(m, "\nSigPnd:\t", &pending);
307 render_sigset_t(m, "ShdPnd:\t", &shpending); 311 render_sigset_t(m, "ShdPnd:\t", &shpending);
308 render_sigset_t(m, "SigBlk:\t", &blocked); 312 render_sigset_t(m, "SigBlk:\t", &blocked);
309 render_sigset_t(m, "SigIgn:\t", &ignored); 313 render_sigset_t(m, "SigIgn:\t", &ignored);
@@ -348,17 +352,20 @@ static inline void task_cap(struct seq_file *m, struct task_struct *p)
348static inline void task_seccomp(struct seq_file *m, struct task_struct *p) 352static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
349{ 353{
350#ifdef CONFIG_SECCOMP 354#ifdef CONFIG_SECCOMP
351 seq_printf(m, "Seccomp:\t%d\n", p->seccomp.mode); 355 seq_puts(m, "Seccomp:\t");
356 seq_put_decimal_ull(m, 0, p->seccomp.mode);
357 seq_putc(m, '\n');
352#endif 358#endif
353} 359}
354 360
355static inline void task_context_switch_counts(struct seq_file *m, 361static inline void task_context_switch_counts(struct seq_file *m,
356 struct task_struct *p) 362 struct task_struct *p)
357{ 363{
358 seq_printf(m, "voluntary_ctxt_switches:\t%lu\n" 364 seq_puts(m, "voluntary_ctxt_switches:\t");
359 "nonvoluntary_ctxt_switches:\t%lu\n", 365 seq_put_decimal_ull(m, 0, p->nvcsw);
360 p->nvcsw, 366 seq_puts(m, "\nnonvoluntary_ctxt_switches:\t");
361 p->nivcsw); 367 seq_put_decimal_ull(m, 0, p->nivcsw);
368 seq_putc(m, '\n');
362} 369}
363 370
364static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) 371static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)