From 22565897da1265120070ed8d7f534bddd37f1a69 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 29 Dec 2003 05:45:53 -0800 Subject: [PATCH] [PATCH] use alloc_percpu in percpu_counters From: Martin Hicks Once NR_CPUS exceeds about 300 ext2 and ext3 will not compile, because the percpu counters in the superblocks are so huge that they cannot be kmalloced. Fix this by converting the percpu_counter mechanism to use alloc_percpu() rather than an NR_CPUS-sized array. --- include/linux/percpu_counter.h | 21 ++++++++++++--------- mm/swap.c | 8 +++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 53c52176c3918..594f564e031a5 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -8,17 +8,14 @@ #include #include #include +#include #ifdef CONFIG_SMP -struct __percpu_counter { - long count; -} ____cacheline_aligned; - struct percpu_counter { spinlock_t lock; long count; - struct __percpu_counter counters[NR_CPUS]; + long *counters; }; #if NR_CPUS >= 16 @@ -29,12 +26,14 @@ struct percpu_counter { static inline void percpu_counter_init(struct percpu_counter *fbc) { - int i; - spin_lock_init(&fbc->lock); fbc->count = 0; - for (i = 0; i < NR_CPUS; i++) - fbc->counters[i].count = 0; + fbc->counters = alloc_percpu(long); +} + +static inline void percpu_counter_destroy(struct percpu_counter *fbc) +{ + free_percpu(fbc->counters); } void percpu_counter_mod(struct percpu_counter *fbc, long amount); @@ -69,6 +68,10 @@ static inline void percpu_counter_init(struct percpu_counter *fbc) fbc->count = 0; } +static inline void percpu_counter_destroy(struct percpu_counter *fbc) +{ +} + static inline void percpu_counter_mod(struct percpu_counter *fbc, long amount) { diff --git a/mm/swap.c b/mm/swap.c index 6c86da966209e..a714334ecb367 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -386,17 +386,19 @@ EXPORT_SYMBOL(vm_acct_memory); #ifdef CONFIG_SMP void percpu_counter_mod(struct percpu_counter *fbc, long amount) { + long count; + long *pcount; int cpu = get_cpu(); - long count = fbc->counters[cpu].count; - count += amount; + pcount = per_cpu_ptr(fbc->counters, cpu); + count = *pcount + 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; + *pcount = count; put_cpu(); } EXPORT_SYMBOL(percpu_counter_mod); -- 2.53.0