Skip to content
This repository was archived by the owner on Dec 2, 2020. It is now read-only.

Commit f7a5f13

Browse files
Alexey Dobriyantorvalds
Alexey Dobriyan
authored andcommitted
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/[email protected] Signed-off-by: Alexey Dobriyan <[email protected]> Cc: Joe Perches <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Al Viro <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 68ba032 commit f7a5f13

File tree

1 file changed

+47
-40
lines changed

1 file changed

+47
-40
lines changed

fs/proc/array.c

+47-40
Original file line numberDiff line numberDiff line change
@@ -186,51 +186,52 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
186186
task_unlock(p);
187187
rcu_read_unlock();
188188

189-
seq_printf(m,
190-
"State:\t%s\n"
191-
"Tgid:\t%d\n"
192-
"Ngid:\t%d\n"
193-
"Pid:\t%d\n"
194-
"PPid:\t%d\n"
195-
"TracerPid:\t%d\n"
196-
"Uid:\t%d\t%d\t%d\t%d\n"
197-
"Gid:\t%d\t%d\t%d\t%d\n"
198-
"FDSize:\t%d\nGroups:\t",
199-
get_task_state(p),
200-
tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid,
201-
from_kuid_munged(user_ns, cred->uid),
202-
from_kuid_munged(user_ns, cred->euid),
203-
from_kuid_munged(user_ns, cred->suid),
204-
from_kuid_munged(user_ns, cred->fsuid),
205-
from_kgid_munged(user_ns, cred->gid),
206-
from_kgid_munged(user_ns, cred->egid),
207-
from_kgid_munged(user_ns, cred->sgid),
208-
from_kgid_munged(user_ns, cred->fsgid),
209-
max_fds);
210-
189+
seq_printf(m, "State:\t%s", get_task_state(p));
190+
191+
seq_puts(m, "\nTgid:\t");
192+
seq_put_decimal_ull(m, 0, tgid);
193+
seq_puts(m, "\nNgid:\t");
194+
seq_put_decimal_ull(m, 0, ngid);
195+
seq_puts(m, "\nPid:\t");
196+
seq_put_decimal_ull(m, 0, pid_nr_ns(pid, ns));
197+
seq_puts(m, "\nPPid:\t");
198+
seq_put_decimal_ull(m, 0, ppid);
199+
seq_puts(m, "\nTracerPid:\t");
200+
seq_put_decimal_ull(m, 0, tpid);
201+
seq_puts(m, "\nUid:");
202+
seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->uid));
203+
seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->euid));
204+
seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->suid));
205+
seq_put_decimal_ull(m, '\t', from_kuid_munged(user_ns, cred->fsuid));
206+
seq_puts(m, "\nGid:");
207+
seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->gid));
208+
seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->egid));
209+
seq_put_decimal_ull(m, '\t', from_kgid_munged(user_ns, cred->sgid));
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");
211215
group_info = cred->group_info;
212216
for (g = 0; g < group_info->ngroups; g++)
213-
seq_printf(m, "%d ",
214-
from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
217+
seq_put_decimal_ull(m, g ? ' ' : 0, from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
215218
put_cred(cred);
219+
/* Trailing space shouldn't have been added in the first place. */
220+
seq_putc(m, ' ');
216221

217222
#ifdef CONFIG_PID_NS
218223
seq_puts(m, "\nNStgid:");
219224
for (g = ns->level; g <= pid->level; g++)
220-
seq_printf(m, "\t%d",
221-
task_tgid_nr_ns(p, pid->numbers[g].ns));
225+
seq_put_decimal_ull(m, '\t', task_tgid_nr_ns(p, pid->numbers[g].ns));
222226
seq_puts(m, "\nNSpid:");
223227
for (g = ns->level; g <= pid->level; g++)
224-
seq_printf(m, "\t%d",
225-
task_pid_nr_ns(p, pid->numbers[g].ns));
228+
seq_put_decimal_ull(m, '\t', task_pid_nr_ns(p, pid->numbers[g].ns));
226229
seq_puts(m, "\nNSpgid:");
227230
for (g = ns->level; g <= pid->level; g++)
228-
seq_printf(m, "\t%d",
229-
task_pgrp_nr_ns(p, pid->numbers[g].ns));
231+
seq_put_decimal_ull(m, '\t', task_pgrp_nr_ns(p, pid->numbers[g].ns));
230232
seq_puts(m, "\nNSsid:");
231233
for (g = ns->level; g <= pid->level; g++)
232-
seq_printf(m, "\t%d",
233-
task_session_nr_ns(p, pid->numbers[g].ns));
234+
seq_put_decimal_ull(m, '\t', task_session_nr_ns(p, pid->numbers[g].ns));
234235
#endif
235236
seq_putc(m, '\n');
236237
}
@@ -299,11 +300,14 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
299300
unlock_task_sighand(p, &flags);
300301
}
301302

302-
seq_printf(m, "Threads:\t%d\n", num_threads);
303-
seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim);
303+
seq_puts(m, "Threads:\t");
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);
304308

305309
/* render them all */
306-
render_sigset_t(m, "SigPnd:\t", &pending);
310+
render_sigset_t(m, "\nSigPnd:\t", &pending);
307311
render_sigset_t(m, "ShdPnd:\t", &shpending);
308312
render_sigset_t(m, "SigBlk:\t", &blocked);
309313
render_sigset_t(m, "SigIgn:\t", &ignored);
@@ -348,17 +352,20 @@ static inline void task_cap(struct seq_file *m, struct task_struct *p)
348352
static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
349353
{
350354
#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');
352358
#endif
353359
}
354360

355361
static inline void task_context_switch_counts(struct seq_file *m,
356362
struct task_struct *p)
357363
{
358-
seq_printf(m, "voluntary_ctxt_switches:\t%lu\n"
359-
"nonvoluntary_ctxt_switches:\t%lu\n",
360-
p->nvcsw,
361-
p->nivcsw);
364+
seq_puts(m, "voluntary_ctxt_switches:\t");
365+
seq_put_decimal_ull(m, 0, p->nvcsw);
366+
seq_puts(m, "\nnonvoluntary_ctxt_switches:\t");
367+
seq_put_decimal_ull(m, 0, p->nivcsw);
368+
seq_putc(m, '\n');
362369
}
363370

364371
static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)

0 commit comments

Comments
 (0)