summaryrefslogtreecommitdiff
path: root/include/linux/percpu_counter.h
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2023-10-11 21:40:09 -0700
committerAndrew Morton <akpm@linux-foundation.org>2023-10-18 14:34:14 -0700
commit1431996bf9088ee59f8017637ab9a7f89909ae63 (patch)
tree8b0533590f06ee436b37353695b35730eb7aa976 /include/linux/percpu_counter.h
parentbeb9868628445306958fd7b2da1cd369a4a381cc (diff)
percpu_counter: extend _limited_add() to negative amounts
Though tmpfs does not need it, percpu_counter_limited_add() can be twice as useful if it works sensibly with negative amounts (subs) - typically decrements towards a limit of 0 or nearby: as suggested by Dave Chinner. And in the course of that reworking, skip the percpu counter sum if it is already obvious that the limit would be passed: as suggested by Tim Chen. Extend the comment above __percpu_counter_limited_add(), defining the behaviour with positive and negative amounts, allowing negative limits, but not bothering about overflow beyond S64_MAX. Link: https://lkml.kernel.org/r/8f86083b-c452-95d4-365b-f16a2e4ebcd4@google.com Signed-off-by: Hugh Dickins <hughd@google.com> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Carlos Maiolino <cem@kernel.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Chuck Lever <chuck.lever@oracle.com> Cc: Darrick J. Wong <djwong@kernel.org> Cc: Dave Chinner <dchinner@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Tim Chen <tim.c.chen@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'include/linux/percpu_counter.h')
-rw-r--r--include/linux/percpu_counter.h11
1 files changed, 9 insertions, 2 deletions
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h
index 8cb7c071bd5c..3a44dd1e33d2 100644
--- a/include/linux/percpu_counter.h
+++ b/include/linux/percpu_counter.h
@@ -198,14 +198,21 @@ static inline bool
percpu_counter_limited_add(struct percpu_counter *fbc, s64 limit, s64 amount)
{
unsigned long flags;
+ bool good = false;
s64 count;
+ if (amount == 0)
+ return true;
+
local_irq_save(flags);
count = fbc->count + amount;
- if (count <= limit)
+ if ((amount > 0 && count <= limit) ||
+ (amount < 0 && count >= limit)) {
fbc->count = count;
+ good = true;
+ }
local_irq_restore(flags);
- return count <= limit;
+ return good;
}
/* non-SMP percpu_counter_add_local is the same with percpu_counter_add */