Skip to contentSkip to conversation

atomic: generalize atomic_add_unless_return

PATCH In review Arun Sharma 3 participants 4 messages Jun 1, 2011 – Jun 6, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 atomic: generalize atomic_add_unless_return

commit 686a7e3 added this primitive to get something going for the stable branch.

Move the primitive to <linux/atomic.h>

Cc Ingo Molnar <[email protected]>
Cc David Miller <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Eric Dumazet <[email protected]>

LKML-Reference: <[email protected]>

---
 include/linux/atomic.h |   14 ++++++++++++++
 net/ipv4/inetpeer.c    |   17 ++---------------
 2 files changed, 16 insertions(+), 15 deletions(-)
include/linux/atomic.h +14 -0
index fc31190..4e2c272 100644
@@ -17,6 +17,20 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 }
 
 /**
+ * atomic_add_unless - add unless the number is already a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as @v was not already @u.
+ * Returns the old value of @v + @a.
+ */
+static inline int atomic_add_unless_return(atomic_t *v, int a, int u)
+{
+	return __atomic_add_unless(v, a, u) + a;
+}
+
+/**
  * atomic_inc_not_zero - increment unless the number is zero
  * @v: pointer of type atomic_t
  *
net/ipv4/inetpeer.c +2 -15
index ce616d9..d4190ae 100644
@@ -203,20 +203,6 @@ static int addr_compare(const struct inetpeer_addr *a,
 	u;							\
 })
 
-static bool atomic_add_unless_return(atomic_t *ptr, int a, int u, int *newv)
-{
-	int cur, old = atomic_read(ptr);
-
-	while (old != u) {
-		*newv = old + a;
-		cur = atomic_cmpxchg(ptr, old, *newv);
-		if (cur == old)
-			return true;
-		old = cur;
-	}
-	return false;
-}
-
 /*
  * Called with rcu_read_lock()
  * Because we hold no lock against a writer, its quite possible we fall
@@ -239,7 +225,8 @@ static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr,
 			 * distinction between an unused entry (refcnt=0) and
 			 * a freed one.
 			 */
-			if (!atomic_add_unless_return(&u->refcnt, 1, -1, newrefcnt))
+			*newrefcnt = atomic_add_unless_return(&u->refcnt, 1, -1);
+			if (*newrefcnt == 0)
 				u = NULL;
 			return u;
 		}
Signature · 1 line
1.7.4
#1 lore raw
Quoted 4 lines · Arun Sharma

commit 686a7e3 added this primitive to get something going for the stable branch.

Move the primitive to <linux/atomic.h>

this changelog is confusing. please replace the pronouns with proper nouns.

Quoted 4 lines
include/linux/atomic.h +0 -0

 /**
+ * atomic_add_unless - add unless the number is already a given value

Quoted 8 lines

+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as @v was not already @u.
+ * Returns the old value of @v + @a.
+ */
+static inline int atomic_add_unless_return(atomic_t *v, int a, int u)

the name of the func in the comment does not match the actual name of the func

also, the semantics here appear to deviate from the other atomic funcs. the existing xxx_return funcs return the new result, not the old.
-mike

#2 lore raw
Quoted 17 lines · Mike Frysinger

include/linux/atomic.h static inline int atomic_add_unless(atomic_t *v, int a, int u) · line 28

Quoted 12 lines · Arun Sharma
include/linux/atomic.h +9 -0
 /**
+ * atomic_add_unless - add unless the number is already a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as @v was not already @u.
+ * Returns the old value of @v + @a.
+ */
+static inline int atomic_add_unless_return(atomic_t *v, int a, int u)

the name of the func in the comment does not match the actual name of the func

Quoted 4 lines

also, the semantics here appear to deviate from the other atomic funcs. the existing xxx_return funcs return the new result, not the old.
-mike

Arun comment is wrong, this function does return the new value of the atomic_t after our operation, not the old ;)

#3 lore raw
Quoted 5 lines · Eric Dumazet
Quoted 5 lines
Quoted 3 lines

+ * Returns the old value of @v + @a.
+ */
+static inline int atomic_add_unless_return(atomic_t *v, int a, int u)

[...]

Quoted 7 lines
Quoted 4 lines

also, the semantics here appear to deviate from the other atomic funcs. the existing xxx_return funcs return the new result, not the old.
-mike

Arun comment is wrong, this function does return the new value of the atomic_t after our operation, not the old ;)

The comment is technically correct:

old value of @v + @a = new value of @v.

I'll try to make it less confusing :)

Mike: Thanks for the review. I'll fix up the commit log and the func name and post a new patch.

-Arun