diff options
| author | Andrew Morton <akpm@digeo.com> | 2003-04-12 12:59:51 -0700 |
|---|---|---|
| committer | James Bottomley <jejb@raven.il.steeleye.com> | 2003-04-12 12:59:51 -0700 |
| commit | ba8e8755393fd032e448b3cfa35cb01743807699 (patch) | |
| tree | 75a18c8515be1213c8d0eea312aedb8e39713aaa /lib | |
| parent | f688c084bc58323c8a7ca19090884ac5da7b6c04 (diff) | |
[PATCH] percpu_counters: approximate but scalable counters
Several places in ext2 and ext3 are using filesystem-wide counters which use
global locking. Mainly for the orlov allocator's heuristics.
To solve the contention which this causes we can trade off accuracy against
speed.
This patch introduces a "percpu_counter" library type in which the counts are
per-cpu and are periodically spilled into a global counter. Readers only
read the global counter.
These objects are *large*. On a 32 CPU P4, they are 4 kbytes. On a 4 way
p3, 128 bytes.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile | 1 | ||||
| -rw-r--r-- | lib/percpu_counter.c | 18 |
2 files changed, 19 insertions, 0 deletions
diff --git a/lib/Makefile b/lib/Makefile index 24e6b3adc098..6ab94d3cb906 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -14,6 +14,7 @@ obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o +obj-$(CONFIG_SMP) += percpu_counter.o ifneq ($(CONFIG_HAVE_DEC_LOCK),y) obj-y += dec_and_lock.o diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c new file mode 100644 index 000000000000..73f99d99f9ac --- /dev/null +++ b/lib/percpu_counter.c @@ -0,0 +1,18 @@ + +#include <linux/percpu_counter.h> + +void percpu_counter_mod(struct percpu_counter *fbc, long amount) +{ + int cpu = get_cpu(); + long count = fbc->counters[cpu].count; + + count += amount; + if (count >= FBC_BATCH || count <= -FBC_BATCH) { + spin_lock(&fbc->lock); + fbc->count += count; + spin_unlock(&fbc->lock); + count = 0; + } + fbc->counters[cpu].count = count; + put_cpu(); +} |
