X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=lib%2Fpercpu_counter.c;h=9659eabffc319c5235669a87687949d270536b4e;hb=fe537c0ee86b27fbe0690a7869815da80f492dbd;hp=c9708db9b8d320b4893f1c4a59f9200c725a0f3d;hpb=3a587f47b82f96f19318c036e7b979fcd5c3848f;p=linux-2.6-omap-h63xx.git diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index c9708db9b8d..9659eabffc3 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) { s64 ret; int cpu; @@ -64,25 +64,43 @@ s64 percpu_counter_sum(struct percpu_counter *fbc) ret += *pcount; } spin_unlock(&fbc->lock); - return ret < 0 ? 0 : ret; + return ret; } -EXPORT_SYMBOL(percpu_counter_sum); +EXPORT_SYMBOL(__percpu_counter_sum); -void percpu_counter_init(struct percpu_counter *fbc, s64 amount) +static struct lock_class_key percpu_counter_irqsafe; + +int percpu_counter_init(struct percpu_counter *fbc, s64 amount) { spin_lock_init(&fbc->lock); fbc->count = amount; fbc->counters = alloc_percpu(s32); + if (!fbc->counters) + return -ENOMEM; #ifdef CONFIG_HOTPLUG_CPU mutex_lock(&percpu_counters_lock); list_add(&fbc->list, &percpu_counters); mutex_unlock(&percpu_counters_lock); #endif + return 0; } EXPORT_SYMBOL(percpu_counter_init); +int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount) +{ + int err; + + err = percpu_counter_init(fbc, amount); + if (!err) + lockdep_set_class(&fbc->lock, &percpu_counter_irqsafe); + return err; +} + void percpu_counter_destroy(struct percpu_counter *fbc) { + if (!fbc->counters) + return; + free_percpu(fbc->counters); #ifdef CONFIG_HOTPLUG_CPU mutex_lock(&percpu_counters_lock);