aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2022-10-17 16:40:49 +0200
committerEric W. Biederman <ebiederm@xmission.com>2022-11-30 12:46:04 -0600
commitb4b11b58cd022df173f2df65633c9c583ade8a65 (patch)
tree9d6c8c43b2d255919d6d9ba85312a78e27910704
parent295227b101925be9a407820b9be9e08c1b87df3d (diff)
downloaduser-namespace-fix-atomic_lock_inc_below-for-v6.2.tar.gz
ucount: Use atomic_long_try_cmpxchg in atomic_long_inc_belowfix-atomic_lock_inc_below-for-v6.2
Use atomic_long_try_cmpxchg instead of atomic_long_cmpxchg (*ptr, old, new) == old in atomic_long_inc_below. x86 CMPXCHG instruction returns success in ZF flag, so this change saves a compare after cmpxchg (and related move instruction in front of cmpxchg). Also, atomic_long_try_cmpxchg implicitly assigns old *ptr value to "old" when cmpxchg fails, enabling further code simplifications. No functional change intended. Signed-off-by: Uros Bizjak <ubizjak@gmail.com> Reviewed-by: Alexey Gladkov <legion@kernel.org> Link: https://lkml.kernel.org/r/20221017144049.3404-3-ubizjak@gmail.com Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--kernel/ucount.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/kernel/ucount.c b/kernel/ucount.c
index 74f5b4959febaf..2c04589a61ff79 100644
--- a/kernel/ucount.c
+++ b/kernel/ucount.c
@@ -214,16 +214,14 @@ void put_ucounts(struct ucounts *ucounts)
static inline bool atomic_long_inc_below(atomic_long_t *v, long u)
{
- long c, old;
- c = atomic_long_read(v);
- for (;;) {
+ long c = atomic_long_read(v);
+
+ do {
if (unlikely(c >= u))
return false;
- old = atomic_long_cmpxchg(v, c, c+1);
- if (likely(old == c))
- return true;
- c = old;
- }
+ } while (!atomic_long_try_cmpxchg(v, &c, c+1));
+
+ return true;
}
struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid,