From e27fba95ee5bce18c0b3b88e36e825ddef6f5bf7 Mon Sep 17 00:00:00 2001 From: THEBOSS Date: Mon, 11 Nov 2019 14:40:26 +0300 Subject: [PATCH] Revert "locking/refcounts: Use atomic_try_cmpxchg()" This reverts commit 75a38ebaed3a7f8cd7a6d2a1032d1d2e23d4f744. --- lib/refcount.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/refcount.c b/lib/refcount.c index 8ec3a3142265..9ab0a42d80d3 100644 --- a/lib/refcount.c +++ b/lib/refcount.c @@ -59,9 +59,9 @@ */ bool refcount_add_not_zero(unsigned int i, refcount_t *r) { - unsigned int new, val = atomic_read(&r->refs); + unsigned int old, new, val = atomic_read(&r->refs); - do { + for (;;) { if (!val) return false; @@ -71,8 +71,12 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r) new = val + i; if (new < val) new = UINT_MAX; + old = atomic_cmpxchg_relaxed(&r->refs, val, new); + if (old == val) + break; - } while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new)); + val = old; + } WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); @@ -116,9 +120,9 @@ EXPORT_SYMBOL_GPL(refcount_add); */ bool refcount_inc_not_zero(refcount_t *r) { - unsigned int new, val = atomic_read(&r->refs); + unsigned int old, new, val = atomic_read(&r->refs); - do { + for (;;) { new = val + 1; if (!val) @@ -127,7 +131,12 @@ bool refcount_inc_not_zero(refcount_t *r) if (unlikely(!new)) return true; - } while (!atomic_try_cmpxchg_relaxed(&r->refs, &val, new)); + old = atomic_cmpxchg_relaxed(&r->refs, val, new); + if (old == val) + break; + + val = old; + } WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); @@ -175,9 +184,9 @@ EXPORT_SYMBOL_GPL(refcount_inc); */ bool refcount_sub_and_test(unsigned int i, refcount_t *r) { - unsigned int new, val = atomic_read(&r->refs); + unsigned int old, new, val = atomic_read(&r->refs); - do { + for (;;) { if (unlikely(val == UINT_MAX)) return false; @@ -187,7 +196,12 @@ bool refcount_sub_and_test(unsigned int i, refcount_t *r) return false; } - } while (!atomic_try_cmpxchg_release(&r->refs, &val, new)); + old = atomic_cmpxchg_release(&r->refs, val, new); + if (old == val) + break; + + val = old; + } return !new; } @@ -247,9 +261,7 @@ EXPORT_SYMBOL(refcount_dec); */ bool refcount_dec_if_one(refcount_t *r) { - int val = 1; - - return atomic_try_cmpxchg_release(&r->refs, &val, 0); + return atomic_cmpxchg_release(&r->refs, 1, 0) == 1; } EXPORT_SYMBOL_GPL(refcount_dec_if_one); @@ -266,9 +278,9 @@ EXPORT_SYMBOL_GPL(refcount_dec_if_one); */ bool refcount_dec_not_one(refcount_t *r) { - unsigned int new, val = atomic_read(&r->refs); + unsigned int old, new, val = atomic_read(&r->refs); - do { + for (;;) { if (unlikely(val == UINT_MAX)) return true; @@ -281,7 +293,12 @@ bool refcount_dec_not_one(refcount_t *r) return true; } - } while (!atomic_try_cmpxchg_release(&r->refs, &val, new)); + old = atomic_cmpxchg_release(&r->refs, val, new); + if (old == val) + break; + + val = old; + } return true; }