X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpercpu_counter.c;h=4a8ba4bf5f6f2b1c0de7d16f794d6d39cbb00d31;hb=e683b423007b9befec30c672c695d0e6abf87493;hp=9659eabffc319c5235669a87687949d270536b4e;hpb=dc62a30e274d003a4d08fb888f1520add4b21373;p=linux-2.6-omap-h63xx.git diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 9659eabffc3..4a8ba4bf5f6 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add); * Add up all the per-cpu counts, return the result. This is a more accurate * but much slower version of percpu_counter_read_positive() */ -s64 __percpu_counter_sum(struct percpu_counter *fbc) +s64 __percpu_counter_sum(struct percpu_counter *fbc, int set) { s64 ret; int cpu; @@ -62,7 +62,12 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc) for_each_online_cpu(cpu) { s32 *pcount = per_cpu_ptr(fbc->counters, cpu); ret += *pcount; + if (set) + *pcount = 0; } + if (set) + fbc->count = ret; + spin_unlock(&fbc->lock); return ret; } @@ -102,6 +107,7 @@ void percpu_counter_destroy(struct percpu_counter *fbc) return; free_percpu(fbc->counters); + fbc->counters = NULL; #ifdef CONFIG_HOTPLUG_CPU mutex_lock(&percpu_counters_lock); list_del(&fbc->list); @@ -124,12 +130,13 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb, mutex_lock(&percpu_counters_lock); list_for_each_entry(fbc, &percpu_counters, list) { s32 *pcount; + unsigned long flags; - spin_lock(&fbc->lock); + spin_lock_irqsave(&fbc->lock, flags); pcount = per_cpu_ptr(fbc->counters, cpu); fbc->count += *pcount; *pcount = 0; - spin_unlock(&fbc->lock); + spin_unlock_irqrestore(&fbc->lock, flags); } mutex_unlock(&percpu_counters_lock); return NOTIFY_OK;