提交 bda7bad6 编写于 作者: K KAMEZAWA Hiroyuki 提交者: Linus Torvalds

procfs: speed up /proc/pid/stat, statm

Process accounting applications as top, ps visit some files under
/proc/<pid>.  With seq_put_decimal_ull(), we can optimize /proc/<pid>/stat
and /proc/<pid>/statm files.

This patch adds
  - seq_put_decimal_ll() for signed values.
  - allow delimiter == 0.
  - convert seq_printf() to seq_put_decimal_ull/ll in /proc/stat, statm.

Test result on a system with 2000+ procs.

Before patch:
  [kamezawa@bluextal test]$ top -b -n 1 | wc -l
  2223
  [kamezawa@bluextal test]$ time top -b -n 1 > /dev/null

  real    0m0.675s
  user    0m0.044s
  sys     0m0.121s

  [kamezawa@bluextal test]$ time ps -elf > /dev/null

  real    0m0.236s
  user    0m0.056s
  sys     0m0.176s

After patch:
  kamezawa@bluextal ~]$ time top -b -n 1 > /dev/null

  real    0m0.657s
  user    0m0.052s
  sys     0m0.100s

  [kamezawa@bluextal ~]$ time ps -elf > /dev/null

  real    0m0.198s
  user    0m0.050s
  sys     0m0.145s

Considering top, ps tend to scan /proc periodically, this will reduce cpu
consumption by top/ps to some extent.

[akpm@linux-foundation.org: checkpatch fixes]
Signed-off-by: NKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 1ac101a5
...@@ -462,59 +462,56 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, ...@@ -462,59 +462,56 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
/* convert nsec -> ticks */ /* convert nsec -> ticks */
start_time = nsec_to_clock_t(start_time); start_time = nsec_to_clock_t(start_time);
seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \ seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ seq_put_decimal_ll(m, ' ', ppid);
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n", seq_put_decimal_ll(m, ' ', pgid);
pid_nr_ns(pid, ns), seq_put_decimal_ll(m, ' ', sid);
tcomm, seq_put_decimal_ll(m, ' ', tty_nr);
state, seq_put_decimal_ll(m, ' ', tty_pgrp);
ppid, seq_put_decimal_ull(m, ' ', task->flags);
pgid, seq_put_decimal_ull(m, ' ', min_flt);
sid, seq_put_decimal_ull(m, ' ', cmin_flt);
tty_nr, seq_put_decimal_ull(m, ' ', maj_flt);
tty_pgrp, seq_put_decimal_ull(m, ' ', cmaj_flt);
task->flags, seq_put_decimal_ull(m, ' ', cputime_to_clock_t(utime));
min_flt, seq_put_decimal_ull(m, ' ', cputime_to_clock_t(stime));
cmin_flt, seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cutime));
maj_flt, seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cstime));
cmaj_flt, seq_put_decimal_ll(m, ' ', priority);
cputime_to_clock_t(utime), seq_put_decimal_ll(m, ' ', nice);
cputime_to_clock_t(stime), seq_put_decimal_ll(m, ' ', num_threads);
cputime_to_clock_t(cutime), seq_put_decimal_ull(m, ' ', 0);
cputime_to_clock_t(cstime), seq_put_decimal_ull(m, ' ', start_time);
priority, seq_put_decimal_ull(m, ' ', vsize);
nice, seq_put_decimal_ll(m, ' ', mm ? get_mm_rss(mm) : 0);
num_threads, seq_put_decimal_ull(m, ' ', rsslim);
start_time, seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0);
vsize, seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0);
mm ? get_mm_rss(mm) : 0, seq_put_decimal_ull(m, ' ', (permitted && mm) ? mm->start_stack : 0);
rsslim, seq_put_decimal_ull(m, ' ', esp);
mm ? (permitted ? mm->start_code : 1) : 0, seq_put_decimal_ull(m, ' ', eip);
mm ? (permitted ? mm->end_code : 1) : 0, /* The signal information here is obsolete.
(permitted && mm) ? mm->start_stack : 0, * It must be decimal for Linux 2.0 compatibility.
esp, * Use /proc/#/status for real-time signals.
eip, */
/* The signal information here is obsolete. seq_put_decimal_ull(m, ' ', task->pending.signal.sig[0] & 0x7fffffffUL);
* It must be decimal for Linux 2.0 compatibility. seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
* Use /proc/#/status for real-time signals. seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
*/ seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
task->pending.signal.sig[0] & 0x7fffffffUL, seq_put_decimal_ull(m, ' ', wchan);
task->blocked.sig[0] & 0x7fffffffUL, seq_put_decimal_ull(m, ' ', 0);
sigign .sig[0] & 0x7fffffffUL, seq_put_decimal_ull(m, ' ', 0);
sigcatch .sig[0] & 0x7fffffffUL, seq_put_decimal_ll(m, ' ', task->exit_signal);
wchan, seq_put_decimal_ll(m, ' ', task_cpu(task));
0UL, seq_put_decimal_ull(m, ' ', task->rt_priority);
0UL, seq_put_decimal_ull(m, ' ', task->policy);
task->exit_signal, seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task));
task_cpu(task), seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime));
task->rt_priority, seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime));
task->policy, seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_data : 0);
(unsigned long long)delayacct_blkio_ticks(task), seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->end_data : 0);
cputime_to_clock_t(gtime), seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_brk : 0);
cputime_to_clock_t(cgtime), seq_putc(m, '\n');
(mm && permitted) ? mm->start_data : 0,
(mm && permitted) ? mm->end_data : 0,
(mm && permitted) ? mm->start_brk : 0);
if (mm) if (mm)
mmput(mm); mmput(mm);
return 0; return 0;
...@@ -542,8 +539,20 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, ...@@ -542,8 +539,20 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
size = task_statm(mm, &shared, &text, &data, &resident); size = task_statm(mm, &shared, &text, &data, &resident);
mmput(mm); mmput(mm);
} }
seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n", /*
size, resident, shared, text, data); * For quick read, open code by putting numbers directly
* expected format is
* seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
* size, resident, shared, text, data);
*/
seq_put_decimal_ull(m, 0, size);
seq_put_decimal_ull(m, ' ', resident);
seq_put_decimal_ull(m, ' ', shared);
seq_put_decimal_ull(m, ' ', text);
seq_put_decimal_ull(m, ' ', 0);
seq_put_decimal_ull(m, ' ', text);
seq_put_decimal_ull(m, ' ', 0);
seq_putc(m, '\n');
return 0; return 0;
} }
...@@ -659,7 +659,8 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, ...@@ -659,7 +659,8 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter,
if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */ if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
goto overflow; goto overflow;
m->buf[m->count++] = delimiter; if (delimiter)
m->buf[m->count++] = delimiter;
if (num < 10) { if (num < 10) {
m->buf[m->count++] = num + '0'; m->buf[m->count++] = num + '0';
...@@ -677,6 +678,24 @@ overflow: ...@@ -677,6 +678,24 @@ overflow:
} }
EXPORT_SYMBOL(seq_put_decimal_ull); EXPORT_SYMBOL(seq_put_decimal_ull);
int seq_put_decimal_ll(struct seq_file *m, char delimiter,
long long num)
{
if (num < 0) {
if (m->count + 3 >= m->size) {
m->count = m->size;
return -1;
}
if (delimiter)
m->buf[m->count++] = delimiter;
num = -num;
delimiter = '-';
}
return seq_put_decimal_ull(m, delimiter, num);
}
EXPORT_SYMBOL(seq_put_decimal_ll);
/** /**
* seq_write - write arbitrary data to buffer * seq_write - write arbitrary data to buffer
* @seq: seq_file identifying the buffer to which data should be written * @seq: seq_file identifying the buffer to which data should be written
......
...@@ -123,6 +123,8 @@ int seq_open_private(struct file *, const struct seq_operations *, int); ...@@ -123,6 +123,8 @@ int seq_open_private(struct file *, const struct seq_operations *, int);
int seq_release_private(struct inode *, struct file *); int seq_release_private(struct inode *, struct file *);
int seq_put_decimal_ull(struct seq_file *m, char delimiter, int seq_put_decimal_ull(struct seq_file *m, char delimiter,
unsigned long long num); unsigned long long num);
int seq_put_decimal_ll(struct seq_file *m, char delimiter,
long long num);
#define SEQ_START_TOKEN ((void *)1) #define SEQ_START_TOKEN ((void *)1)
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册