On Thu, 5 Oct 2023, Chen, Tim C wrote: > >--- a/lib/percpu_counter.c > >+++ b/lib/percpu_counter.c > >@@ -278,6 +278,59 @@ int __percpu_counter_compare(struct > >percpu_counter *fbc, s64 rhs, s32 batch) } > >EXPORT_SYMBOL(__percpu_counter_compare); > > > >+/* > >+ * Compare counter, and add amount if the total is within limit. > >+ * Return true if amount was added, false if it would exceed limit. > >+ */ > >+bool __percpu_counter_limited_add(struct percpu_counter *fbc, > >+ s64 limit, s64 amount, s32 batch) { > >+ s64 count; > >+ s64 unknown; > >+ unsigned long flags; > >+ bool good; > >+ > >+ if (amount > limit) > >+ return false; > >+ > >+ local_irq_save(flags); > >+ unknown = batch * num_online_cpus(); > >+ count = __this_cpu_read(*fbc->counters); > >+ > >+ /* Skip taking the lock when safe */ > >+ if (abs(count + amount) <= batch && > >+ fbc->count + unknown <= limit) { > >+ this_cpu_add(*fbc->counters, amount); > >+ local_irq_restore(flags); > >+ return true; > >+ } > >+ > >+ raw_spin_lock(&fbc->lock); > >+ count = fbc->count + amount; > >+ > > Perhaps we can fast path the case where for sure > we will exceed limit? > > if (fbc->count + amount - unknown > limit) > return false; Thanks, that sounds reasonable: I'll try to add something like that - but haven't thought about it carefully enough yet (too easy for me to overlook some negative case which messes everything up). Hugh