All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	mingo@kernel.org, will.deacon@arm.com,
	paulmck@linux.vnet.ibm.com,
	Haavard Skinnemoen <hskinnemoen@gmail.com>
Subject: Re: [PATCH 06/20] arch,avr32: Fold atomic_ops
Date: Sat, 31 May 2014 16:14:45 +0200	[thread overview]
Message-ID: <20140531141445.GD16155@laptop.programming.kicks-ass.net> (raw)
In-Reply-To: <20140513204032.GB14023@samfundet.no>

On Tue, May 13, 2014 at 10:40:32PM +0200, Hans-Christian Egtvedt wrote:
> Probably found the reason why we want to use sub with the signed 21-bit
> limit, it uses one less register than the add instruction that can add up to
> 32-bit values.
> 
> Both instructions are 32-bit, to use a 16-bit instruction the immediate is
> very small; 4 bit.
> 
> sub 32-bit, type IV, takes a register and subtracts a 21-bit immediate.
> add 32-bit, type II, adds two register values together.

How about something like so? It fixes the problem that your
atomic_sub*() can only deal with a 21bit offset, while the general
kernel interface assumes it can deal with the full 32 bits.

It also adds the above as a comment, hopefully explaining the 21bit
magic to the next person stumbling over this.


---
 arch/avr32/include/asm/atomic.h |  121 +++++++++++++++++++---------------------
 1 file changed, 60 insertions(+), 61 deletions(-)

--- a/arch/avr32/include/asm/atomic.h
+++ b/arch/avr32/include/asm/atomic.h
@@ -22,30 +22,43 @@
 #define atomic_read(v)		(*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)	(((v)->counter) = i)
 
+#define ATOMIC_OP_RETURN(op, asm_op, asm_con)				\
+static inline int __atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	int result;							\
+									\
+	asm volatile(							\
+		"/* atomic_" #op "_return */\n"				\
+		"1:	ssrf	5\n"					\
+		"	ld.w	%0, %2\n"				\
+		"	" #asm_op "	%0, %3\n"			\
+		"	stcond	%1, %0\n"				\
+		"	brne	1b"					\
+		: "=&r" (result), "=o" (v->counter)			\
+		: "m" (v->counter), #asm_con (i)			\
+		: "cc");						\
+									\
+	return result;							\
+}
+
+ATOMIC_OP_RETURN(sub, sub, rKs21)
+ATOMIC_OP_RETURN(add, add, i)
+
+#undef ATOMIC_OP_RETURN
+
 /*
- * atomic_sub_return - subtract the atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
+ * Probably found the reason why we want to use sub with the signed 21-bit
+ * limit, it uses one less register than the add instruction that can add up to
+ * 32-bit values.
  *
- * Atomically subtracts @i from @v. Returns the resulting value.
+ * Both instructions are 32-bit, to use a 16-bit instruction the immediate is
+ * very small; 4 bit.
+ *
+ * sub 32-bit, type IV, takes a register and subtracts a 21-bit immediate.
+ * add 32-bit, type II, adds two register values together.
  */
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
-	int result;
-
-	asm volatile(
-		"/* atomic_sub_return */\n"
-		"1:	ssrf	5\n"
-		"	ld.w	%0, %2\n"
-		"	sub	%0, %3\n"
-		"	stcond	%1, %0\n"
-		"	brne	1b"
-		: "=&r"(result), "=o"(v->counter)
-		: "m"(v->counter), "rKs21"(i)
-		: "cc");
-
-	return result;
-}
+#define IS_21BIT_CONST(i)						\
+	(__builtin_constant_p(i) && ((i) >= -1048575) && ((i) <= 1048576))
 
 /*
  * atomic_add_return - add integer to atomic variable
@@ -56,51 +69,25 @@ static inline int atomic_sub_return(int
  */
 static inline int atomic_add_return(int i, atomic_t *v)
 {
-	int result;
+	if (IS_21BIT_CONST(i))
+		return __atomic_sub_return(-i, v);
 
-	if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
-		result = atomic_sub_return(-i, v);
-	else
-		asm volatile(
-			"/* atomic_add_return */\n"
-			"1:	ssrf	5\n"
-			"	ld.w	%0, %1\n"
-			"	add	%0, %3\n"
-			"	stcond	%2, %0\n"
-			"	brne	1b"
-			: "=&r"(result), "=o"(v->counter)
-			: "m"(v->counter), "r"(i)
-			: "cc", "memory");
-
-	return result;
+	return __atomic_add_return(i, v);
 }
 
 /*
- * atomic_sub_unless - sub unless the number is a given value
+ * atomic_sub_return - subtract the atomic variable
+ * @i: integer value to subtract
  * @v: pointer of type atomic_t
- * @a: the amount to subtract from v...
- * @u: ...unless v is equal to u.
  *
- * Atomically subtract @a from @v, so long as it was not @u.
- * Returns the old value of @v.
-*/
-static inline void atomic_sub_unless(atomic_t *v, int a, int u)
+ * Atomically subtracts @i from @v. Returns the resulting value.
+ */
+static inline int atomic_sub_return(int i, atomic_t *v)
 {
-	int tmp;
+	if (IS_21BIT_CONST(i))
+		return __atomic_sub_return(i, v);
 
-	asm volatile(
-		"/* atomic_sub_unless */\n"
-		"1:	ssrf	5\n"
-		"	ld.w	%0, %2\n"
-		"	cp.w	%0, %4\n"
-		"	breq	1f\n"
-		"	sub	%0, %3\n"
-		"	stcond	%1, %0\n"
-		"	brne	1b\n"
-		"1:"
-		: "=&r"(tmp), "=o"(v->counter)
-		: "m"(v->counter), "rKs21"(a), "rKs21"(u)
-		: "cc", "memory");
+	return __atomic_add_return(-i, v);
 }
 
 /*
@@ -116,9 +103,21 @@ static inline int __atomic_add_unless(at
 {
 	int tmp, old = atomic_read(v);
 
-	if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
-		atomic_sub_unless(v, -a, u);
-	else {
+	if (IS_21BIT_CONST(a)) {
+		asm volatile(
+			"/* __atomic_sub_unless */\n"
+			"1:	ssrf	5\n"
+			"	ld.w	%0, %2\n"
+			"	cp.w	%0, %4\n"
+			"	breq	1f\n"
+			"	sub	%0, %3\n"
+			"	stcond	%1, %0\n"
+			"	brne	1b\n"
+			"1:"
+			: "=&r"(tmp), "=o"(v->counter)
+			: "m"(v->counter), "rKs21"(-a), "rKs21"(u)
+			: "cc", "memory");
+	} else {
 		asm volatile(
 			"/* __atomic_add_unless */\n"
 			"1:	ssrf	5\n"

  parent reply	other threads:[~2014-05-31 14:14 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-08 13:58 [PATCH 00/20] arch atomic 'cleanup' Peter Zijlstra
2014-05-08 13:58 ` [PATCH 01/20] x86: Kill atomic_or_long() Peter Zijlstra
2014-08-14 17:18   ` [tip:locking/arch] locking,x86: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 02/20] arch,alpha: Fold atomic_ops Peter Zijlstra
2014-08-14 17:18   ` [tip:locking/arch] locking,arch,alpha: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 03/20] arch,arc: " Peter Zijlstra
2014-05-09  9:34   ` Vineet Gupta
2014-05-09 10:22     ` Peter Zijlstra
2014-08-14 17:19   ` [tip:locking/arch] locking,arch,arc: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 04/20] arch,arm: " Peter Zijlstra
2014-05-08 18:31   ` Will Deacon
2014-08-14 17:19   ` [tip:locking/arch] locking,arch,arm: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 05/20] arch,arm64: " Peter Zijlstra
2014-05-08 18:31   ` Will Deacon
2014-08-14 17:19   ` [tip:locking/arch] locking,arch,arm64: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 06/20] arch,avr32: " Peter Zijlstra
2014-05-09 18:32   ` Hans-Christian Egtvedt
2014-05-09 20:43     ` Peter Zijlstra
2014-05-09 20:51       ` Peter Zijlstra
2014-05-09 21:17         ` Peter Zijlstra
2014-05-13 20:40           ` Hans-Christian Egtvedt
2014-05-13 20:50             ` Peter Zijlstra
2014-05-14  7:43               ` Hans-Christian Egtvedt
2014-05-31 14:14             ` Peter Zijlstra [this message]
2014-06-06  6:25               ` Hans-Christian Egtvedt
2014-08-14 17:19               ` [tip:locking/arch] locking,arch,avr32: " tip-bot for Peter Zijlstra
2014-08-14 19:27                 ` Hans-Christian Egtvedt
2014-08-14 19:30                   ` Peter Zijlstra
2014-08-14 19:32                     ` Hans-Christian Egtvedt
2014-05-08 13:58 ` [PATCH 07/20] arch,cris: " Peter Zijlstra
2014-05-08 15:12   ` Geert Uytterhoeven
2014-05-08 16:06     ` Peter Zijlstra
2014-05-08 17:34       ` David Miller
2014-05-08 18:17         ` Peter Zijlstra
2014-05-08 20:27           ` David Miller
2014-05-09  8:14           ` Jesper Nilsson
2014-08-14 17:19   ` [tip:locking/arch] locking,arch,cris: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 08/20] arch,hexagon: " Peter Zijlstra
2014-05-12 17:28   ` rkuo
2014-08-14 17:20   ` [tip:locking/arch] locking,arch,hexagon: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 09/20] arch,ia64: " Peter Zijlstra
2014-08-14 17:20   ` [tip:locking/arch] locking,arch,ia64: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 10/20] arch,m32r: " Peter Zijlstra
2014-08-14 17:20   ` [tip:locking/arch] locking,arch,m32r: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 11/20] arch,m68k: " Peter Zijlstra
2014-05-09  9:08   ` Geert Uytterhoeven
2014-05-09  9:16     ` Peter Zijlstra
2014-05-09  9:44       ` Geert Uytterhoeven
2014-08-14 17:20       ` [tip:locking/arch] locking,arch,m68k: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 12/20] arch,metag: " Peter Zijlstra
2014-05-13 10:06   ` James Hogan
2014-05-13 10:06     ` James Hogan
2014-08-14 17:21   ` [tip:locking/arch] locking,arch,metag: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 13/20] arch,mips: " Peter Zijlstra
2014-08-14 17:21   ` [tip:locking/arch] locking,arch,mips: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 14/20] arch,mn10300: " Peter Zijlstra
2014-05-20 13:05   ` David Howells
2014-05-20 13:16     ` Peter Zijlstra
2014-08-14 17:21   ` [tip:locking/arch] locking,arch,mn10300: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 15/20] arch,parisc: " Peter Zijlstra
2014-08-14 17:21   ` [tip:locking/arch] locking,arch,parisc: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 16/20] arch,powerpc: " Peter Zijlstra
2014-08-14 17:22   ` [tip:locking/arch] locking,arch,powerpc: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 17/20] arch,sh: " Peter Zijlstra
2014-08-14 17:22   ` [tip:locking/arch] locking,arch,sh: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 18/20] arch,sparc: " Peter Zijlstra
2014-08-14 17:22   ` [tip:locking/arch] locking,arch,sparc: " tip-bot for Peter Zijlstra
2014-05-08 13:58 ` [PATCH 19/20] arch,xtensa: " Peter Zijlstra
2014-08-14 17:22   ` [tip:locking/arch] locking,arch,xtensa: " tip-bot for Peter Zijlstra
2014-05-08 13:59 ` [PATCH 20/20] arch: Rewrite generic atomic support Peter Zijlstra
2014-05-08 15:24   ` Sam Ravnborg
2014-05-08 18:26     ` Peter Zijlstra
2014-08-14 17:23   ` [tip:locking/arch] locking,arch: " tip-bot for Peter Zijlstra
2014-09-24 16:54 ` [PATCH 00/20] arch atomic 'cleanup' Will Deacon
2014-09-24 18:06   ` Peter Zijlstra
2014-09-24 18:09     ` Will Deacon
2014-09-25  5:03     ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140531141445.GD16155@laptop.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=egtvedt@samfundet.no \
    --cc=hskinnemoen@gmail.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=torvalds@linux-foundation.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.