diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2010-10-27 18:34:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:03:13 -0400 |
commit | 478735e38887077ac77a9756121b6ce0cb956e2f (patch) | |
tree | 7b42110f71b1711f56cbbc0a01f00894b221337d /fs/proc/stat.c | |
parent | f2c66cd8eeddedb440f33bc0f5cec1ed7ae376cb (diff) |
/proc/stat: fix scalability of irq sum of all cpu
In /proc/stat, the number of per-IRQ event is shown by making a sum each
irq's events on all cpus. But we can make use of kstat_irqs().
kstat_irqs() do the same calculation, If !CONFIG_GENERIC_HARDIRQ,
it's not a big cost. (Both of the number of cpus and irqs are small.)
If a system is very big and CONFIG_GENERIC_HARDIRQ, it does
for_each_irq()
for_each_cpu()
- look up a radix tree
- read desc->irq_stat[cpu]
This seems not efficient. This patch adds kstat_irqs() for
CONFIG_GENRIC_HARDIRQ and change the calculation as
for_each_irq()
look up radix tree
for_each_cpu()
- read desc->irq_stat[cpu]
This reduces cost.
A test on (4096cpusp, 256 nodes, 4592 irqs) host (by Jack Steiner)
%time cat /proc/stat > /dev/null
Before Patch: 2.459 sec
After Patch : .561 sec
[akpm@linux-foundation.org: unexport kstat_irqs, coding-style tweaks]
[akpm@linux-foundation.org: fix unused variable 'per_irq_sum']
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Tested-by: Jack Steiner <steiner@sgi.com>
Acked-by: Jack Steiner <steiner@sgi.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
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 | 10 |
1 files changed, 2 insertions, 8 deletions
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index b80c620565bf..e15a19c93bae 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -31,7 +31,6 @@ static int show_stat(struct seq_file *p, void *v) | |||
31 | u64 sum_softirq = 0; | 31 | u64 sum_softirq = 0; |
32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | 32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; |
33 | struct timespec boottime; | 33 | struct timespec boottime; |
34 | unsigned int per_irq_sum; | ||
35 | 34 | ||
36 | user = nice = system = idle = iowait = | 35 | user = nice = system = idle = iowait = |
37 | irq = softirq = steal = cputime64_zero; | 36 | irq = softirq = steal = cputime64_zero; |
@@ -108,13 +107,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
108 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 107 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
109 | 108 | ||
110 | /* sum again ? it could be updated? */ | 109 | /* sum again ? it could be updated? */ |
111 | for_each_irq_nr(j) { | 110 | for_each_irq_nr(j) |
112 | per_irq_sum = 0; | 111 | seq_printf(p, " %u", kstat_irqs(j)); |
113 | for_each_possible_cpu(i) | ||
114 | per_irq_sum += kstat_irqs_cpu(j, i); | ||
115 | |||
116 | seq_printf(p, " %u", per_irq_sum); | ||
117 | } | ||
118 | 112 | ||
119 | seq_printf(p, | 113 | seq_printf(p, |
120 | "\nctxt %llu\n" | 114 | "\nctxt %llu\n" |