diff options
author | Andrew Morton <akpm@linux-foundation.org> | 2007-07-16 02:39:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:41 -0400 |
commit | c67ad917cbf21b2862e2cf8e8b28339872ef7927 (patch) | |
tree | 362d8cf8668998b8cd5deb611693f584b8df5ee5 /include/linux/percpu_counter.h | |
parent | 85420ccad1610f123365eec89848ef25641bc6b7 (diff) |
percpu_counters(): use cpu notifiers
per-cpu counters presently must iterate over all possible CPUs in the
exhaustive percpu_counter_sum().
But it can be much better to only iterate over the presently-online CPUs. To
do this, we must arrange for an offlined CPU's count to be spilled into the
counter's central count.
We can do this for all percpu_counters in the machine by linking them into a
single global list and walking that list at CPU_DEAD time.
(I hope. Might have race windows in which the percpu_counter_sum() count is
inaccurate?)
Cc: Gautham R Shenoy <ego@in.ibm.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/percpu_counter.h')
-rw-r--r-- | include/linux/percpu_counter.h | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index f5aa593ccf32..3d9f70972cdf 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/spinlock.h> | 9 | #include <linux/spinlock.h> |
10 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
11 | #include <linux/list.h> | ||
11 | #include <linux/threads.h> | 12 | #include <linux/threads.h> |
12 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
@@ -17,6 +18,9 @@ | |||
17 | struct percpu_counter { | 18 | struct percpu_counter { |
18 | spinlock_t lock; | 19 | spinlock_t lock; |
19 | s64 count; | 20 | s64 count; |
21 | #ifdef CONFIG_HOTPLUG_CPU | ||
22 | struct list_head list; /* All percpu_counters are on a list */ | ||
23 | #endif | ||
20 | s32 *counters; | 24 | s32 *counters; |
21 | }; | 25 | }; |
22 | 26 | ||
@@ -26,18 +30,8 @@ struct percpu_counter { | |||
26 | #define FBC_BATCH (NR_CPUS*4) | 30 | #define FBC_BATCH (NR_CPUS*4) |
27 | #endif | 31 | #endif |
28 | 32 | ||
29 | static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount) | 33 | void percpu_counter_init(struct percpu_counter *fbc, s64 amount); |
30 | { | 34 | void percpu_counter_destroy(struct percpu_counter *fbc); |
31 | spin_lock_init(&fbc->lock); | ||
32 | fbc->count = amount; | ||
33 | fbc->counters = alloc_percpu(s32); | ||
34 | } | ||
35 | |||
36 | static inline void percpu_counter_destroy(struct percpu_counter *fbc) | ||
37 | { | ||
38 | free_percpu(fbc->counters); | ||
39 | } | ||
40 | |||
41 | void percpu_counter_mod(struct percpu_counter *fbc, s32 amount); | 35 | void percpu_counter_mod(struct percpu_counter *fbc, s32 amount); |
42 | s64 percpu_counter_sum(struct percpu_counter *fbc); | 36 | s64 percpu_counter_sum(struct percpu_counter *fbc); |
43 | 37 | ||