Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Aug 2018 09:39:32 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r337527 - in head/sys/compat/linuxkpi/common/include: asm linux
Message-ID:  <201808090939.w799dWIV014139@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu Aug  9 09:39:32 2018
New Revision: 337527
URL: https://svnweb.freebsd.org/changeset/base/337527

Log:
  Use atomic_fcmpset_XXX() instead of atomic_cmpset_XXX() when possible
  in the LinuxKPI.
  
  Suggested by:	mjg @
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/asm/atomic-long.h
  head/sys/compat/linuxkpi/common/include/asm/atomic.h
  head/sys/compat/linuxkpi/common/include/asm/atomic64.h
  head/sys/compat/linuxkpi/common/include/linux/bitops.h

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic-long.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic-long.h	Thu Aug  9 09:06:30 2018	(r337526)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic-long.h	Thu Aug  9 09:39:32 2018	(r337527)
@@ -87,9 +87,8 @@ atomic_long_cmpxchg(atomic_long_t *v, long old, long n
 	long ret = old;
 
 	for (;;) {
-		if (atomic_cmpset_long(&v->counter, old, new))
+		if (atomic_fcmpset_long(&v->counter, &ret, new))
 			break;
-		ret = READ_ONCE(v->counter);
 		if (ret != old)
 			break;
 	}
@@ -99,13 +98,12 @@ atomic_long_cmpxchg(atomic_long_t *v, long old, long n
 static inline int
 atomic_long_add_unless(atomic_long_t *v, long a, long u)
 {
-	long c;
+	long c = atomic_long_read(v);
 
 	for (;;) {
-		c = atomic_long_read(v);
 		if (unlikely(c == u))
 			break;
-		if (likely(atomic_cmpset_long(&v->counter, c, c + a)))
+		if (likely(atomic_fcmpset_long(&v->counter, &c, c + a)))
 			break;
 	}
 	return (c != u);

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic.h	Thu Aug  9 09:06:30 2018	(r337526)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic.h	Thu Aug  9 09:39:32 2018	(r337527)
@@ -108,13 +108,12 @@ atomic_dec(atomic_t *v)
 static inline int
 atomic_add_unless(atomic_t *v, int a, int u)
 {
-	int c;
+	int c = atomic_read(v);
 
 	for (;;) {
-		c = atomic_read(v);
 		if (unlikely(c == u))
 			break;
-		if (likely(atomic_cmpset_int(&v->counter, c, c + a)))
+		if (likely(atomic_fcmpset_int(&v->counter, &c, c + a)))
 			break;
 	}
 	return (c != u);
@@ -132,12 +131,10 @@ atomic_xchg(atomic_t *v, int i)
 #if !defined(__mips__)
 	return (atomic_swap_int(&v->counter, i));
 #else
-	int ret;
-	for (;;) {
-		ret = READ_ONCE(v->counter);
-		if (atomic_cmpset_int(&v->counter, ret, i))
-			break;
-	}
+	int ret = atomic_read(v);
+
+	while (!atomic_fcmpset_int(&v->counter, &ret, i))
+		;
 	return (ret);
 #endif
 }
@@ -148,9 +145,8 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
 	int ret = old;
 
 	for (;;) {
-		if (atomic_cmpset_int(&v->counter, old, new))
+		if (atomic_fcmpset_int(&v->counter, &ret, new))
 			break;
-		ret = READ_ONCE(v->counter);
 		if (ret != old)
 			break;
 	}

Modified: head/sys/compat/linuxkpi/common/include/asm/atomic64.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/asm/atomic64.h	Thu Aug  9 09:06:30 2018	(r337526)
+++ head/sys/compat/linuxkpi/common/include/asm/atomic64.h	Thu Aug  9 09:39:32 2018	(r337527)
@@ -92,13 +92,12 @@ atomic64_dec(atomic64_t *v)
 static inline int64_t
 atomic64_add_unless(atomic64_t *v, int64_t a, int64_t u)
 {
-	int64_t c;
+	int64_t c = atomic64_read(v);
 
 	for (;;) {
-		c = atomic64_read(v);
 		if (unlikely(c == u))
 			break;
-		if (likely(atomic_cmpset_64(&v->counter, c, c + a)))
+		if (likely(atomic_fcmpset_64(&v->counter, &c, c + a)))
 			break;
 	}
 	return (c != u);
@@ -111,12 +110,10 @@ atomic64_xchg(atomic64_t *v, int64_t i)
     (defined(__powerpc__) && !defined(__powerpc64__)))
 	return (atomic_swap_64(&v->counter, i));
 #else
-	int64_t ret;
-	for (;;) {
-		ret = READ_ONCE(v->counter);
-		if (atomic_cmpset_64(&v->counter, ret, i))
-			break;
-	}
+	int64_t ret = atomic64_read(v);
+
+	while (!atomic_fcmpset_64(&v->counter, &ret, i))
+		;
 	return (ret);
 #endif
 }
@@ -127,9 +124,8 @@ atomic64_cmpxchg(atomic64_t *v, int64_t old, int64_t n
 	int64_t ret = old;
 
 	for (;;) {
-		if (atomic_cmpset_64(&v->counter, old, new))
+		if (atomic_fcmpset_64(&v->counter, &ret, new))
 			break;
-		ret = READ_ONCE(v->counter);
 		if (ret != old)
 			break;
 	}

Modified: head/sys/compat/linuxkpi/common/include/linux/bitops.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/bitops.h	Thu Aug  9 09:06:30 2018	(r337526)
+++ head/sys/compat/linuxkpi/common/include/linux/bitops.h	Thu Aug  9 09:39:32 2018	(r337527)
@@ -282,10 +282,10 @@ test_and_clear_bit(long bit, volatile unsigned long *v
 	var += BIT_WORD(bit);
 	bit %= BITS_PER_LONG;
 	bit = (1UL << bit);
-	do {
-		val = *var;
-	} while (atomic_cmpset_long(var, val, val & ~bit) == 0);
 
+	val = *var;
+	while (!atomic_fcmpset_long(var, &val, val & ~bit))
+		;
 	return !!(val & bit);
 }
 
@@ -312,10 +312,10 @@ test_and_set_bit(long bit, volatile unsigned long *var
 	var += BIT_WORD(bit);
 	bit %= BITS_PER_LONG;
 	bit = (1UL << bit);
-	do {
-		val = *var;
-	} while (atomic_cmpset_long(var, val, val | bit) == 0);
 
+	val = *var;
+	while (!atomic_fcmpset_long(var, &val, val | bit))
+		;
 	return !!(val & bit);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808090939.w799dWIV014139>