All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC+CFT] Use word operations in bitops
@ 2011-01-16 12:19 ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-16 12:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-omap

XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
I strongly suggest you ensure you have a copy of your filesystems before
trying this patch.

The patch below switches the bitops to use word loads/stores rather than
byte operations - so that we can avoid using the ldrexb/strexb instructions
which are only supported from ARMv6k and up.

The current bitops prevent a single kernel covering ARMv6 and ARMv7
architectures without the resulting kernel being unsafe on SMP.  As
ldrex/strex is supported from ARMv6 upwards, but ldrexb/strexb is not,
switch these functions to use the word-based loads/stores.

As our bitops functions have been tolerant of misaligned pointers, they
now include a check which will do a NULL pointer store in the event that
they're passed a non-aligned pointers: ldrex/strex can't cope with such
things.

I've verified in userspace that these give the same results on LE setups
as our existing implementation - that doesn't mean these aren't buggy, it
just means they appear to behave the same for the testing I've done.  BE
is completely untested (I don't have any ARM BE setups.)

Someone who uses BE setups needs to check that filesystem images (for
minix and ext2/ext3) which worked prior to this patch continue to work
after these patches.

This does need a fair amount of testing before it can be merged, so I'd
like to see a number of Tested-by's against this patch.  Please also
indicate whether you tested on LE or BE or both, which filesystems, and
whether they were read-only mounted or read-write mounted.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/bitops.h |  125 +++++++-------------------
 arch/arm/kernel/armksyms.c    |   33 ++-----
 arch/arm/lib/bitops.h         |   43 ++++++----
 arch/arm/lib/changebit.S      |   10 +--
 arch/arm/lib/clearbit.S       |   11 +--
 arch/arm/lib/findbit.S        |  197 ++++++++++++++--------------------------
 arch/arm/lib/setbit.S         |   11 +--
 arch/arm/lib/testchangebit.S  |    9 +--
 arch/arm/lib/testclearbit.S   |    9 +--
 arch/arm/lib/testsetbit.S     |    9 +--
 10 files changed, 155 insertions(+), 302 deletions(-)

diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 7b1bb2b..da813b0 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,90 +149,47 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  */
 
 /*
- * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
+ * Assembly bitops.  nr = 0 -> word 0 bit 0.
  */
-extern void _set_bit_le(int nr, volatile unsigned long * p);
-extern void _clear_bit_le(int nr, volatile unsigned long * p);
-extern void _change_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(const void * p, unsigned size);
-extern int _find_next_zero_bit_le(const void * p, int size, int offset);
-extern int _find_first_bit_le(const unsigned long *p, unsigned size);
-extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
-
-/*
- * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
- */
-extern void _set_bit_be(int nr, volatile unsigned long * p);
-extern void _clear_bit_be(int nr, volatile unsigned long * p);
-extern void _change_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_be(const void * p, unsigned size);
-extern int _find_next_zero_bit_be(const void * p, int size, int offset);
-extern int _find_first_bit_be(const unsigned long *p, unsigned size);
-extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+extern int _find_first_zero_bit(const unsigned long * p, unsigned size);
+extern int _find_next_zero_bit(const unsigned long * p, int size, int offset);
+extern int _find_first_bit(const unsigned long *p, unsigned size);
+extern int _find_next_bit(const unsigned long *p, int size, int offset);
 
 #ifndef CONFIG_SMP
 /*
  * The __* form of bitops are non-atomic and may be reordered.
  */
-#define	ATOMIC_BITOP_LE(name,nr,p)		\
+#define	ATOMIC_BITOP(name,nr,p)			\
 	(__builtin_constant_p(nr) ?		\
 	 ____atomic_##name(nr, p) :		\
-	 _##name##_le(nr,p))
-
-#define	ATOMIC_BITOP_BE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_be(nr,p))
+	 _##name(nr,p))
 #else
-#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
-#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
+#define ATOMIC_BITOP(name,nr,p)	_##name(nr,p)
 #endif
 
 #define NONATOMIC_BITOP(name,nr,p)		\
 	(____nonatomic_##name(nr, p))
 
-#ifndef __ARMEB__
 /*
- * These are the little endian, atomic definitions.
+ * These are the endian-indifferent as they use word loads/stores.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_LE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_LE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
-#define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
-#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
-#define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
-#define find_next_bit(p,sz,off)		_find_next_bit_le(p,sz,off)
-
-#define WORD_BITOFF_TO_LE(x)		((x))
-
-#else
-
-/*
- * These are the big endian, atomic definitions.
- */
-#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_BE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_BE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
-#define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)
-#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_be(p,sz,off)
-#define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
-#define find_next_bit(p,sz,off)		_find_next_bit_be(p,sz,off)
-
-#define WORD_BITOFF_TO_LE(x)		((x) ^ 0x18)
-
-#endif
+#define set_bit(nr,p)			ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p)			ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p)		ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p)		ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p)	ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p)	ATOMIC_BITOP(test_and_change_bit,nr,p)
+#define find_first_zero_bit(p,sz)	_find_first_zero_bit(p,sz)
+#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit(p,sz,off)
+#define find_first_bit(p,sz)		_find_first_bit(p,sz)
+#define find_next_bit(p,sz,off)		_find_next_bit(p,sz,off)
 
 #if __LINUX_ARM_ARCH__ < 5
 
@@ -302,42 +259,28 @@ static inline int fls(int x)
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/minix.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)			\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit(nr, (unsigned long *)(p))
 #define ext2_set_bit_atomic(lock,nr,p)          \
-                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_set_bit(nr, (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)			\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit(nr, (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_clear_bit(nr, (unsigned long *)(p))
 #define ext2_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit(nr, (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		_find_first_zero_bit((unsigned long *)(p),sz)
 #define ext2_find_next_zero_bit(p,sz,off)	\
-		_find_next_zero_bit_le(p,sz,off)
+		_find_next_zero_bit((unsigned long *)(p),sz,off)
 #define ext2_find_next_bit(p, sz, off) \
-		_find_next_bit_le(p, sz, off)
-
-/*
- * Minix is defined to use little-endian byte ordering.
- * These do not need to be atomic.
- */
-#define minix_set_bit(nr,p)			\
-		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_and_set_bit(nr,p)		\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_and_clear_bit(nr,p)		\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		_find_next_bit((unsigned long *)(p), sz, off)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 9615423..7064ef4 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,29 +140,16 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
 #endif
 
 	/* bitops */
-EXPORT_SYMBOL(_set_bit_le);
-EXPORT_SYMBOL(_test_and_set_bit_le);
-EXPORT_SYMBOL(_clear_bit_le);
-EXPORT_SYMBOL(_test_and_clear_bit_le);
-EXPORT_SYMBOL(_change_bit_le);
-EXPORT_SYMBOL(_test_and_change_bit_le);
-EXPORT_SYMBOL(_find_first_zero_bit_le);
-EXPORT_SYMBOL(_find_next_zero_bit_le);
-EXPORT_SYMBOL(_find_first_bit_le);
-EXPORT_SYMBOL(_find_next_bit_le);
-
-#ifdef __ARMEB__
-EXPORT_SYMBOL(_set_bit_be);
-EXPORT_SYMBOL(_test_and_set_bit_be);
-EXPORT_SYMBOL(_clear_bit_be);
-EXPORT_SYMBOL(_test_and_clear_bit_be);
-EXPORT_SYMBOL(_change_bit_be);
-EXPORT_SYMBOL(_test_and_change_bit_be);
-EXPORT_SYMBOL(_find_first_zero_bit_be);
-EXPORT_SYMBOL(_find_next_zero_bit_be);
-EXPORT_SYMBOL(_find_first_bit_be);
-EXPORT_SYMBOL(_find_next_bit_be);
-#endif
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
+EXPORT_SYMBOL(_find_first_zero_bit);
+EXPORT_SYMBOL(_find_next_zero_bit);
+EXPORT_SYMBOL(_find_first_bit);
+EXPORT_SYMBOL(_find_next_bit);
 
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_OLD_MCOUNT
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index d422529..2a09e57 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,28 +1,34 @@
 
 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
 	.macro	bitop, instr
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	and	r3, r0, #7		@ Get bit offset
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	\instr	r2, r2, r3
-	strexb	r0, r2, [r1]
+	strex	r0, r2, [r1]
 	cmp	r0, #0
 	bne	1b
 	mov	pc, lr
 	.endm
 
 	.macro	testop, instr, store
-	and	r3, r0, #7		@ Get bit offset
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3		@ create mask
 	smp_dmb
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	ands	r0, r2, r3		@ save old value of bit
-	\instr	r2, r2, r3			@ toggle bit
-	strexb	ip, r2, [r1]
+	\instr	r2, r2, r3		@ toggle bit
+	strex	ip, r2, [r1]
 	cmp	ip, #0
 	bne	1b
 	smp_dmb
@@ -32,13 +38,16 @@
 	.endm
 #else
 	.macro	bitop, instr
-	and	r2, r0, #7
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r2, r0, #31
+	mov	r0, r0, lsr #5
 	mov	r3, #1
 	mov	r3, r3, lsl r2
 	save_and_disable_irqs ip
-	ldrb	r2, [r1, r0, lsr #3]
+	ldr	r2, [r1, r0, lsl #2]
 	\instr	r2, r2, r3
-	strb	r2, [r1, r0, lsr #3]
+	str	r2, [r1, r0, lsl #2]
 	restore_irqs ip
 	mov	pc, lr
 	.endm
@@ -52,11 +61,13 @@
  * to avoid dirtying the data cache.
  */
 	.macro	testop, instr, store
-	add	r1, r1, r0, lsr #3
-	and	r3, r0, #7
-	mov	r0, #1
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r3, r0, #31
+	mov	r0, r0, lsr #5
 	save_and_disable_irqs ip
-	ldrb	r2, [r1]
+	ldr	r2, [r1, r0, lsl #2]!
+	mov	r0, #1
 	tst	r2, r0, lsl r3
 	\instr	r2, r2, r0, lsl r3
 	\store	r2, [r1]
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 80f3115..68ed5b6 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -12,12 +12,6 @@
 #include "bitops.h"
                 .text
 
-/* Purpose  : Function to change a bit
- * Prototype: int change_bit(int bit, void *addr)
- */
-ENTRY(_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_change_bit_le)
+ENTRY(_change_bit)
 	bitop	eor
-ENDPROC(_change_bit_be)
-ENDPROC(_change_bit_le)
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 1a63e43..4c04c3b 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
                 .text
 
-/*
- * Purpose  : Function to clear a bit
- * Prototype: int clear_bit(int bit, void *addr)
- */
-ENTRY(_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_clear_bit_le)
+ENTRY(_clear_bit)
 	bitop	bic
-ENDPROC(_clear_bit_be)
-ENDPROC(_clear_bit_le)
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 64f6bc1..223e92a 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -21,173 +21,114 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
-ENTRY(_find_first_zero_bit_le)
+ENTRY(_find_first_zero_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0	
-		beq	3f
+		beq	ffz_none
 		mov	r2, #0
-1:
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ffz_loop:
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eors	r3, r3, #0xff		@ invert bits
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
+ THUMB(		ldr	r3, [r0, r3]		)
+		mvns	r3, r3			@ invert bits
+		bne	.L_found0		@ any now set - found zero bit
+ffz_next:	add	r2, r2, #32		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		blo	ffz_loop
+ffz_none:	mov	r0, r1			@ no free bits
 		mov	pc, lr
-ENDPROC(_find_first_zero_bit_le)
+ENDPROC(_find_first_zero_bit)
 
 /*
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(_find_next_zero_bit_le)
+ENTRY(_find_next_zero_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+		beq	ffz_none
+		ands	ip, r2, #31
+		beq	ffz_loop
+		bic	r2, r2, #31
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eor	r3, r3, #0xff		@ now looking for a 1 bit
+ THUMB(		ldr	r3, [r0, r3]		)
+		mvn	r3, r3			@ now looking for a 1 bit
 		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_zero_bit_le)
+		bne	.L_foundoff
+		b	ffz_next		@ loop for next bit
+ENDPROC(_find_next_zero_bit)
 
 /*
  * Purpose  : Find a 'one' bit
  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  */
-ENTRY(_find_first_bit_le)
+ENTRY(_find_first_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0	
-		beq	3f
+		beq	ffb_none
 		mov	r2, #0
-1:
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ffb_loop:
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
+ THUMB(		ldr	r3, [r0, r3]		)
 		movs	r3, r3
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
+		bne	.L_found0		@ any now set - found zero bit
+ffb_next:	add	r2, r2, #32		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		blo	ffb_loop
+ffb_none:	mov	r0, r1			@ no free bits
 		mov	pc, lr
-ENDPROC(_find_first_bit_le)
+ENDPROC(_find_first_bit)
 
 /*
  * Purpose  : Find next 'one' bit
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(_find_next_bit_le)
+ENTRY(_find_next_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+		beq	ffb_none
+		ands	ip, r2, #31
+		beq	ffb_loop		@ If new word, goto old routine
+		bic	r2, r2, #31
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
+ THUMB(		ldr	r3, [r0, r3]		)
 		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_bit_le)
-
-#ifdef __ARMEB__
-
-ENTRY(_find_first_zero_bit_be)
-		teq	r1, #0
-		beq	3f
-		mov	r2, #0
-1:		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eors	r3, r3, #0xff		@ invert bits
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
-		mov	pc, lr
-ENDPROC(_find_first_zero_bit_be)
-
-ENTRY(_find_next_zero_bit_be)
-		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
-		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eor	r3, r3, #0xff		@ now looking for a 1 bit
-		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_zero_bit_be)
-
-ENTRY(_find_first_bit_be)
-		teq	r1, #0
-		beq	3f
-		mov	r2, #0
-1:		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		movs	r3, r3
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
-		mov	pc, lr
-ENDPROC(_find_first_bit_be)
-
-ENTRY(_find_next_bit_be)
-		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
-		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_bit_be)
-
-#endif
+		bne	.L_foundoff
+		b	ffb_loop		@ loop for next bit
+ENDPROC(_find_next_bit)
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
  */
-.L_found:
-#if __LINUX_ARM_ARCH__ >= 5
-		rsb	r0, r3, #0
+.L_foundoff:	add	r2, r2, ip		@ add bit offset back in
+.L_found0:	rsb	r0, r3, #0
 		and	r3, r3, r0
+#if __LINUX_ARM_ARCH__ >= 5
 		clz	r3, r3
 		rsb	r3, r3, #31
 		add	r0, r2, r3
 #else
-		tst	r3, #0x0f
-		addeq	r2, r2, #4
-		movne	r3, r3, lsl #4
-		tst	r3, #0x30
-		addeq	r2, r2, #2
-		movne	r3, r3, lsl #2
-		tst	r3, #0x40
-		addeq	r2, r2, #1
+		movs	r0, r3, lsr #16
+		addne	r2, r2, #16
+		movne	r3, r0
+		movs	r0, r3, lsr #8
+		addne	r2, r2, #8
+		movne	r3, r0
+		movs	r0, r3, lsr #4
+		addne	r2, r2, #4
+		movne	r3, r0
+		movs	r0, r3, lsr #2
+		addne	r2, r2, #2
+		movne	r3, r0
+		tst	r3, #2
+		addne	r2, r2, #1
 		mov	r0, r2
 #endif
 		cmp	r1, r0			@ Clamp to maxbit
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 1dd7176..bbee5c6 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
 		.text
 
-/*
- * Purpose  : Function to set a bit
- * Prototype: int set_bit(int bit, void *addr)
- */
-ENTRY(_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_set_bit_le)
+ENTRY(_set_bit)
 	bitop	orr
-ENDPROC(_set_bit_be)
-ENDPROC(_set_bit_le)
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index 5c98dc5..15a4d43 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_change_bit_le)
-	testop	eor, strb
-ENDPROC(_test_and_change_bit_be)
-ENDPROC(_test_and_change_bit_le)
+ENTRY(_test_and_change_bit)
+	testop	eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 543d709..521b66b 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_clear_bit_le)
-	testop	bicne, strneb
-ENDPROC(_test_and_clear_bit_be)
-ENDPROC(_test_and_clear_bit_le)
+ENTRY(_test_and_clear_bit)
+	testop	bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 0b3f390..1c98cc2 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_set_bit_le)
-	testop	orreq, streqb
-ENDPROC(_test_and_set_bit_be)
-ENDPROC(_test_and_set_bit_le)
+ENTRY(_test_and_set_bit)
+	testop	orreq, streq
+ENDPROC(_test_and_set_bit)

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-16 12:19 ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-16 12:19 UTC (permalink / raw)
  To: linux-arm-kernel

XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
I strongly suggest you ensure you have a copy of your filesystems before
trying this patch.

The patch below switches the bitops to use word loads/stores rather than
byte operations - so that we can avoid using the ldrexb/strexb instructions
which are only supported from ARMv6k and up.

The current bitops prevent a single kernel covering ARMv6 and ARMv7
architectures without the resulting kernel being unsafe on SMP.  As
ldrex/strex is supported from ARMv6 upwards, but ldrexb/strexb is not,
switch these functions to use the word-based loads/stores.

As our bitops functions have been tolerant of misaligned pointers, they
now include a check which will do a NULL pointer store in the event that
they're passed a non-aligned pointers: ldrex/strex can't cope with such
things.

I've verified in userspace that these give the same results on LE setups
as our existing implementation - that doesn't mean these aren't buggy, it
just means they appear to behave the same for the testing I've done.  BE
is completely untested (I don't have any ARM BE setups.)

Someone who uses BE setups needs to check that filesystem images (for
minix and ext2/ext3) which worked prior to this patch continue to work
after these patches.

This does need a fair amount of testing before it can be merged, so I'd
like to see a number of Tested-by's against this patch.  Please also
indicate whether you tested on LE or BE or both, which filesystems, and
whether they were read-only mounted or read-write mounted.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/bitops.h |  125 +++++++-------------------
 arch/arm/kernel/armksyms.c    |   33 ++-----
 arch/arm/lib/bitops.h         |   43 ++++++----
 arch/arm/lib/changebit.S      |   10 +--
 arch/arm/lib/clearbit.S       |   11 +--
 arch/arm/lib/findbit.S        |  197 ++++++++++++++--------------------------
 arch/arm/lib/setbit.S         |   11 +--
 arch/arm/lib/testchangebit.S  |    9 +--
 arch/arm/lib/testclearbit.S   |    9 +--
 arch/arm/lib/testsetbit.S     |    9 +--
 10 files changed, 155 insertions(+), 302 deletions(-)

diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 7b1bb2b..da813b0 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,90 +149,47 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  */
 
 /*
- * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
+ * Assembly bitops.  nr = 0 -> word 0 bit 0.
  */
-extern void _set_bit_le(int nr, volatile unsigned long * p);
-extern void _clear_bit_le(int nr, volatile unsigned long * p);
-extern void _change_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(const void * p, unsigned size);
-extern int _find_next_zero_bit_le(const void * p, int size, int offset);
-extern int _find_first_bit_le(const unsigned long *p, unsigned size);
-extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
-
-/*
- * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
- */
-extern void _set_bit_be(int nr, volatile unsigned long * p);
-extern void _clear_bit_be(int nr, volatile unsigned long * p);
-extern void _change_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_be(const void * p, unsigned size);
-extern int _find_next_zero_bit_be(const void * p, int size, int offset);
-extern int _find_first_bit_be(const unsigned long *p, unsigned size);
-extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+extern int _find_first_zero_bit(const unsigned long * p, unsigned size);
+extern int _find_next_zero_bit(const unsigned long * p, int size, int offset);
+extern int _find_first_bit(const unsigned long *p, unsigned size);
+extern int _find_next_bit(const unsigned long *p, int size, int offset);
 
 #ifndef CONFIG_SMP
 /*
  * The __* form of bitops are non-atomic and may be reordered.
  */
-#define	ATOMIC_BITOP_LE(name,nr,p)		\
+#define	ATOMIC_BITOP(name,nr,p)			\
 	(__builtin_constant_p(nr) ?		\
 	 ____atomic_##name(nr, p) :		\
-	 _##name##_le(nr,p))
-
-#define	ATOMIC_BITOP_BE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_be(nr,p))
+	 _##name(nr,p))
 #else
-#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
-#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
+#define ATOMIC_BITOP(name,nr,p)	_##name(nr,p)
 #endif
 
 #define NONATOMIC_BITOP(name,nr,p)		\
 	(____nonatomic_##name(nr, p))
 
-#ifndef __ARMEB__
 /*
- * These are the little endian, atomic definitions.
+ * These are the endian-indifferent as they use word loads/stores.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_LE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_LE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
-#define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
-#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
-#define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
-#define find_next_bit(p,sz,off)		_find_next_bit_le(p,sz,off)
-
-#define WORD_BITOFF_TO_LE(x)		((x))
-
-#else
-
-/*
- * These are the big endian, atomic definitions.
- */
-#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_BE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_BE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
-#define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)
-#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_be(p,sz,off)
-#define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
-#define find_next_bit(p,sz,off)		_find_next_bit_be(p,sz,off)
-
-#define WORD_BITOFF_TO_LE(x)		((x) ^ 0x18)
-
-#endif
+#define set_bit(nr,p)			ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p)			ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p)		ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p)		ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p)	ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p)	ATOMIC_BITOP(test_and_change_bit,nr,p)
+#define find_first_zero_bit(p,sz)	_find_first_zero_bit(p,sz)
+#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit(p,sz,off)
+#define find_first_bit(p,sz)		_find_first_bit(p,sz)
+#define find_next_bit(p,sz,off)		_find_next_bit(p,sz,off)
 
 #if __LINUX_ARM_ARCH__ < 5
 
@@ -302,42 +259,28 @@ static inline int fls(int x)
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/minix.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)			\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit(nr, (unsigned long *)(p))
 #define ext2_set_bit_atomic(lock,nr,p)          \
-                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_set_bit(nr, (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)			\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit(nr, (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_clear_bit(nr, (unsigned long *)(p))
 #define ext2_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit(nr, (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		_find_first_zero_bit((unsigned long *)(p),sz)
 #define ext2_find_next_zero_bit(p,sz,off)	\
-		_find_next_zero_bit_le(p,sz,off)
+		_find_next_zero_bit((unsigned long *)(p),sz,off)
 #define ext2_find_next_bit(p, sz, off) \
-		_find_next_bit_le(p, sz, off)
-
-/*
- * Minix is defined to use little-endian byte ordering.
- * These do not need to be atomic.
- */
-#define minix_set_bit(nr,p)			\
-		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_and_set_bit(nr,p)		\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_test_and_clear_bit(nr,p)		\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
-#define minix_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		_find_next_bit((unsigned long *)(p), sz, off)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 9615423..7064ef4 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,29 +140,16 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
 #endif
 
 	/* bitops */
-EXPORT_SYMBOL(_set_bit_le);
-EXPORT_SYMBOL(_test_and_set_bit_le);
-EXPORT_SYMBOL(_clear_bit_le);
-EXPORT_SYMBOL(_test_and_clear_bit_le);
-EXPORT_SYMBOL(_change_bit_le);
-EXPORT_SYMBOL(_test_and_change_bit_le);
-EXPORT_SYMBOL(_find_first_zero_bit_le);
-EXPORT_SYMBOL(_find_next_zero_bit_le);
-EXPORT_SYMBOL(_find_first_bit_le);
-EXPORT_SYMBOL(_find_next_bit_le);
-
-#ifdef __ARMEB__
-EXPORT_SYMBOL(_set_bit_be);
-EXPORT_SYMBOL(_test_and_set_bit_be);
-EXPORT_SYMBOL(_clear_bit_be);
-EXPORT_SYMBOL(_test_and_clear_bit_be);
-EXPORT_SYMBOL(_change_bit_be);
-EXPORT_SYMBOL(_test_and_change_bit_be);
-EXPORT_SYMBOL(_find_first_zero_bit_be);
-EXPORT_SYMBOL(_find_next_zero_bit_be);
-EXPORT_SYMBOL(_find_first_bit_be);
-EXPORT_SYMBOL(_find_next_bit_be);
-#endif
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
+EXPORT_SYMBOL(_find_first_zero_bit);
+EXPORT_SYMBOL(_find_next_zero_bit);
+EXPORT_SYMBOL(_find_first_bit);
+EXPORT_SYMBOL(_find_next_bit);
 
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_OLD_MCOUNT
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index d422529..2a09e57 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,28 +1,34 @@
 
 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
 	.macro	bitop, instr
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	and	r3, r0, #7		@ Get bit offset
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	\instr	r2, r2, r3
-	strexb	r0, r2, [r1]
+	strex	r0, r2, [r1]
 	cmp	r0, #0
 	bne	1b
 	mov	pc, lr
 	.endm
 
 	.macro	testop, instr, store
-	and	r3, r0, #7		@ Get bit offset
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3		@ create mask
 	smp_dmb
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	ands	r0, r2, r3		@ save old value of bit
-	\instr	r2, r2, r3			@ toggle bit
-	strexb	ip, r2, [r1]
+	\instr	r2, r2, r3		@ toggle bit
+	strex	ip, r2, [r1]
 	cmp	ip, #0
 	bne	1b
 	smp_dmb
@@ -32,13 +38,16 @@
 	.endm
 #else
 	.macro	bitop, instr
-	and	r2, r0, #7
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r2, r0, #31
+	mov	r0, r0, lsr #5
 	mov	r3, #1
 	mov	r3, r3, lsl r2
 	save_and_disable_irqs ip
-	ldrb	r2, [r1, r0, lsr #3]
+	ldr	r2, [r1, r0, lsl #2]
 	\instr	r2, r2, r3
-	strb	r2, [r1, r0, lsr #3]
+	str	r2, [r1, r0, lsl #2]
 	restore_irqs ip
 	mov	pc, lr
 	.endm
@@ -52,11 +61,13 @@
  * to avoid dirtying the data cache.
  */
 	.macro	testop, instr, store
-	add	r1, r1, r0, lsr #3
-	and	r3, r0, #7
-	mov	r0, #1
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r3, r0, #31
+	mov	r0, r0, lsr #5
 	save_and_disable_irqs ip
-	ldrb	r2, [r1]
+	ldr	r2, [r1, r0, lsl #2]!
+	mov	r0, #1
 	tst	r2, r0, lsl r3
 	\instr	r2, r2, r0, lsl r3
 	\store	r2, [r1]
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 80f3115..68ed5b6 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -12,12 +12,6 @@
 #include "bitops.h"
                 .text
 
-/* Purpose  : Function to change a bit
- * Prototype: int change_bit(int bit, void *addr)
- */
-ENTRY(_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_change_bit_le)
+ENTRY(_change_bit)
 	bitop	eor
-ENDPROC(_change_bit_be)
-ENDPROC(_change_bit_le)
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 1a63e43..4c04c3b 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
                 .text
 
-/*
- * Purpose  : Function to clear a bit
- * Prototype: int clear_bit(int bit, void *addr)
- */
-ENTRY(_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_clear_bit_le)
+ENTRY(_clear_bit)
 	bitop	bic
-ENDPROC(_clear_bit_be)
-ENDPROC(_clear_bit_le)
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 64f6bc1..223e92a 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -21,173 +21,114 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
-ENTRY(_find_first_zero_bit_le)
+ENTRY(_find_first_zero_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0	
-		beq	3f
+		beq	ffz_none
 		mov	r2, #0
-1:
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ffz_loop:
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eors	r3, r3, #0xff		@ invert bits
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
+ THUMB(		ldr	r3, [r0, r3]		)
+		mvns	r3, r3			@ invert bits
+		bne	.L_found0		@ any now set - found zero bit
+ffz_next:	add	r2, r2, #32		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		blo	ffz_loop
+ffz_none:	mov	r0, r1			@ no free bits
 		mov	pc, lr
-ENDPROC(_find_first_zero_bit_le)
+ENDPROC(_find_first_zero_bit)
 
 /*
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(_find_next_zero_bit_le)
+ENTRY(_find_next_zero_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+		beq	ffz_none
+		ands	ip, r2, #31
+		beq	ffz_loop
+		bic	r2, r2, #31
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eor	r3, r3, #0xff		@ now looking for a 1 bit
+ THUMB(		ldr	r3, [r0, r3]		)
+		mvn	r3, r3			@ now looking for a 1 bit
 		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_zero_bit_le)
+		bne	.L_foundoff
+		b	ffz_next		@ loop for next bit
+ENDPROC(_find_next_zero_bit)
 
 /*
  * Purpose  : Find a 'one' bit
  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  */
-ENTRY(_find_first_bit_le)
+ENTRY(_find_first_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0	
-		beq	3f
+		beq	ffb_none
 		mov	r2, #0
-1:
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ffb_loop:
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
+ THUMB(		ldr	r3, [r0, r3]		)
 		movs	r3, r3
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
+		bne	.L_found0		@ any now set - found zero bit
+ffb_next:	add	r2, r2, #32		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		blo	ffb_loop
+ffb_none:	mov	r0, r1			@ no free bits
 		mov	pc, lr
-ENDPROC(_find_first_bit_le)
+ENDPROC(_find_first_bit)
 
 /*
  * Purpose  : Find next 'one' bit
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(_find_next_bit_le)
+ENTRY(_find_next_bit)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word aligned
 		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
- ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+		beq	ffb_none
+		ands	ip, r2, #31
+		beq	ffb_loop		@ If new word, goto old routine
+		bic	r2, r2, #31
+ ARM(		ldr	r3, [r0, r2, lsr #3]	)
  THUMB(		lsr	r3, r2, #3		)
- THUMB(		ldrb	r3, [r0, r3]		)
+ THUMB(		ldr	r3, [r0, r3]		)
 		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_bit_le)
-
-#ifdef __ARMEB__
-
-ENTRY(_find_first_zero_bit_be)
-		teq	r1, #0
-		beq	3f
-		mov	r2, #0
-1:		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eors	r3, r3, #0xff		@ invert bits
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
-		mov	pc, lr
-ENDPROC(_find_first_zero_bit_be)
-
-ENTRY(_find_next_zero_bit_be)
-		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
-		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		eor	r3, r3, #0xff		@ now looking for a 1 bit
-		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_zero_bit_be)
-
-ENTRY(_find_first_bit_be)
-		teq	r1, #0
-		beq	3f
-		mov	r2, #0
-1:		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		movs	r3, r3
-		bne	.L_found		@ any now set - found zero bit
-		add	r2, r2, #8		@ next bit pointer
-2:		cmp	r2, r1			@ any more?
-		blo	1b
-3:		mov	r0, r1			@ no free bits
-		mov	pc, lr
-ENDPROC(_find_first_bit_be)
-
-ENTRY(_find_next_bit_be)
-		teq	r1, #0
-		beq	3b
-		ands	ip, r2, #7
-		beq	1b			@ If new byte, goto old routine
-		eor	r3, r2, #0x18		@ big endian byte ordering
- ARM(		ldrb	r3, [r0, r3, lsr #3]	)
- THUMB(		lsr	r3, #3			)
- THUMB(		ldrb	r3, [r0, r3]		)
-		movs	r3, r3, lsr ip		@ shift off unused bits
-		bne	.L_found
-		orr	r2, r2, #7		@ if zero, then no bits here
-		add	r2, r2, #1		@ align bit pointer
-		b	2b			@ loop for next bit
-ENDPROC(_find_next_bit_be)
-
-#endif
+		bne	.L_foundoff
+		b	ffb_loop		@ loop for next bit
+ENDPROC(_find_next_bit)
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
  */
-.L_found:
-#if __LINUX_ARM_ARCH__ >= 5
-		rsb	r0, r3, #0
+.L_foundoff:	add	r2, r2, ip		@ add bit offset back in
+.L_found0:	rsb	r0, r3, #0
 		and	r3, r3, r0
+#if __LINUX_ARM_ARCH__ >= 5
 		clz	r3, r3
 		rsb	r3, r3, #31
 		add	r0, r2, r3
 #else
-		tst	r3, #0x0f
-		addeq	r2, r2, #4
-		movne	r3, r3, lsl #4
-		tst	r3, #0x30
-		addeq	r2, r2, #2
-		movne	r3, r3, lsl #2
-		tst	r3, #0x40
-		addeq	r2, r2, #1
+		movs	r0, r3, lsr #16
+		addne	r2, r2, #16
+		movne	r3, r0
+		movs	r0, r3, lsr #8
+		addne	r2, r2, #8
+		movne	r3, r0
+		movs	r0, r3, lsr #4
+		addne	r2, r2, #4
+		movne	r3, r0
+		movs	r0, r3, lsr #2
+		addne	r2, r2, #2
+		movne	r3, r0
+		tst	r3, #2
+		addne	r2, r2, #1
 		mov	r0, r2
 #endif
 		cmp	r1, r0			@ Clamp to maxbit
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 1dd7176..bbee5c6 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
 		.text
 
-/*
- * Purpose  : Function to set a bit
- * Prototype: int set_bit(int bit, void *addr)
- */
-ENTRY(_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_set_bit_le)
+ENTRY(_set_bit)
 	bitop	orr
-ENDPROC(_set_bit_be)
-ENDPROC(_set_bit_le)
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index 5c98dc5..15a4d43 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_change_bit_le)
-	testop	eor, strb
-ENDPROC(_test_and_change_bit_be)
-ENDPROC(_test_and_change_bit_le)
+ENTRY(_test_and_change_bit)
+	testop	eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 543d709..521b66b 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_clear_bit_le)
-	testop	bicne, strneb
-ENDPROC(_test_and_clear_bit_be)
-ENDPROC(_test_and_clear_bit_le)
+ENTRY(_test_and_clear_bit)
+	testop	bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 0b3f390..1c98cc2 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_set_bit_le)
-	testop	orreq, streqb
-ENDPROC(_test_and_set_bit_be)
-ENDPROC(_test_and_set_bit_le)
+ENTRY(_test_and_set_bit)
+	testop	orreq, streq
+ENDPROC(_test_and_set_bit)

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-16 12:19 ` Russell King - ARM Linux
@ 2011-01-16 18:15   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-16 18:15 UTC (permalink / raw)
  To: linux-arm-kernel, linux-omap

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
> I strongly suggest you ensure you have a copy of your filesystems before
> trying this patch.
> 
> The patch below switches the bitops to use word loads/stores rather than
> byte operations - so that we can avoid using the ldrexb/strexb instructions
> which are only supported from ARMv6k and up.
> 
> The current bitops prevent a single kernel covering ARMv6 and ARMv7
> architectures without the resulting kernel being unsafe on SMP.  As
> ldrex/strex is supported from ARMv6 upwards, but ldrexb/strexb is not,
> switch these functions to use the word-based loads/stores.
> 
> As our bitops functions have been tolerant of misaligned pointers, they
> now include a check which will do a NULL pointer store in the event that
> they're passed a non-aligned pointers: ldrex/strex can't cope with such
> things.
> 
> I've verified in userspace that these give the same results on LE setups
> as our existing implementation - that doesn't mean these aren't buggy, it
> just means they appear to behave the same for the testing I've done.  BE
> is completely untested (I don't have any ARM BE setups.)
> 
> Someone who uses BE setups needs to check that filesystem images (for
> minix and ext2/ext3) which worked prior to this patch continue to work
> after these patches.
> 
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Revised patch - the previous one was slightly buggered for BE.  We also
don't need to touch the findbit operations at all, so that part has been
dropped.

This includes a patch by Akinobu Mita ("arm: introduce little-endian
bitops", v4).

 arch/arm/include/asm/bitops.h |  114 +++++++++++++++++++++--------------------
 arch/arm/kernel/armksyms.c    |   18 ++----
 arch/arm/lib/bitops.h         |   46 ++++++++++-------
 arch/arm/lib/changebit.S      |   10 +---
 arch/arm/lib/clearbit.S       |   11 +---
 arch/arm/lib/findbit.S        |   16 ++++++
 arch/arm/lib/setbit.S         |   11 +---
 arch/arm/lib/testchangebit.S  |    9 +--
 arch/arm/lib/testclearbit.S   |    9 +--
 arch/arm/lib/testsetbit.S     |    9 +--
 10 files changed, 124 insertions(+), 129 deletions(-)

diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 338ff19..1e8c366 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,30 +149,28 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  */
 
 /*
+ * Native endian assembly bitops.  nr = 0 -> word 0 bit 0.
+ */
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+
+/*
  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
  */
-extern void _set_bit_le(int nr, volatile unsigned long * p);
-extern void _clear_bit_le(int nr, volatile unsigned long * p);
-extern void _change_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(const void * p, unsigned size);
-extern int _find_next_zero_bit_le(const void * p, int size, int offset);
+extern int _find_first_zero_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_zero_bit_le(const unsigned long *p, int size, int offset);
 extern int _find_first_bit_le(const unsigned long *p, unsigned size);
 extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
 /*
  * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
  */
-extern void _set_bit_be(int nr, volatile unsigned long * p);
-extern void _clear_bit_be(int nr, volatile unsigned long * p);
-extern void _change_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_be(const void * p, unsigned size);
-extern int _find_next_zero_bit_be(const void * p, int size, int offset);
+extern int _find_first_zero_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_zero_bit_be(const unsigned long *p, int size, int offset);
 extern int _find_first_bit_be(const unsigned long *p, unsigned size);
 extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 
@@ -180,33 +178,26 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 /*
  * The __* form of bitops are non-atomic and may be reordered.
  */
-#define	ATOMIC_BITOP_LE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_le(nr,p))
-
-#define	ATOMIC_BITOP_BE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_be(nr,p))
+#define ATOMIC_BITOP(name,nr,p)			\
+	(__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
 #else
-#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
-#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
+#define ATOMIC_BITOP(name,nr,p)		_##name(nr,p)
 #endif
 
-#define NONATOMIC_BITOP(name,nr,p)		\
-	(____nonatomic_##name(nr, p))
+/*
+ * Native endian atomic definitions.
+ */
+#define set_bit(nr,p)			ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p)			ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p)		ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p)		ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p)	ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p)	ATOMIC_BITOP(test_and_change_bit,nr,p)
 
 #ifndef __ARMEB__
 /*
  * These are the little endian, atomic definitions.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_LE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_LE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
 #define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
 #define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
 #define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
@@ -215,16 +206,9 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 #define WORD_BITOFF_TO_LE(x)		((x))
 
 #else
-
 /*
  * These are the big endian, atomic definitions.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_BE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_BE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
 #define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)
 #define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_be(p,sz,off)
 #define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
@@ -303,41 +287,61 @@ static inline int fls(int x)
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
 
+#define __set_bit_le(nr, p)			\
+	__set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __clear_bit_le(nr, p)			\
+	__clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __test_and_set_bit_le(nr, p)			\
+		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_and_set_bit_le(nr, p)          \
+		test_and_set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __test_and_clear_bit_le(nr, p)			\
+		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_and_clear_bit_le(nr, p)	\
+		test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_bit_le(nr, p)			\
+		test_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define find_first_zero_bit_le(p, sz)		\
+		_find_first_zero_bit_le(p, sz)
+#define find_next_zero_bit_le(p, sz, off)	\
+		_find_next_zero_bit_le(p, sz, off)
+#define find_next_bit_le(p, sz, off) \
+		_find_next_bit_le(p, sz, off)
 /*
  * Ext2 is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)			\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit_le(nr, (unsigned long *)(p))
 #define ext2_set_bit_atomic(lock,nr,p)          \
-                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_and_set_bit_le(nr, (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)			\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define ext2_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit_le(nr, (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		find_first_zero_bit_le((unsigned long *)(p), sz)
 #define ext2_find_next_zero_bit(p,sz,off)	\
-		_find_next_zero_bit_le(p,sz,off)
+		find_next_zero_bit_le((unsigned long *)(p), sz, off)
 #define ext2_find_next_bit(p, sz, off) \
-		_find_next_bit_le(p, sz, off)
+		find_next_bit_le((unsigned long *)(p), sz, off)
 
 /*
  * Minix is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define minix_set_bit(nr,p)			\
-		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__set_bit_le(nr, (unsigned long *)(p))
 #define minix_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit_le(nr, (unsigned long *)(p))
 #define minix_test_and_set_bit(nr,p)		\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit_le(nr, (unsigned long *)(p))
 #define minix_test_and_clear_bit(nr,p)		\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define minix_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		find_first_zero_bit_le((unsigned long *)(p), sz)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index e5e1e53..d5d4185 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,24 +140,18 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
 #endif
 
 	/* bitops */
-EXPORT_SYMBOL(_set_bit_le);
-EXPORT_SYMBOL(_test_and_set_bit_le);
-EXPORT_SYMBOL(_clear_bit_le);
-EXPORT_SYMBOL(_test_and_clear_bit_le);
-EXPORT_SYMBOL(_change_bit_le);
-EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
 EXPORT_SYMBOL(_find_first_zero_bit_le);
 EXPORT_SYMBOL(_find_next_zero_bit_le);
 EXPORT_SYMBOL(_find_first_bit_le);
 EXPORT_SYMBOL(_find_next_bit_le);
 
 #ifdef __ARMEB__
-EXPORT_SYMBOL(_set_bit_be);
-EXPORT_SYMBOL(_test_and_set_bit_be);
-EXPORT_SYMBOL(_clear_bit_be);
-EXPORT_SYMBOL(_test_and_clear_bit_be);
-EXPORT_SYMBOL(_change_bit_be);
-EXPORT_SYMBOL(_test_and_change_bit_be);
 EXPORT_SYMBOL(_find_first_zero_bit_be);
 EXPORT_SYMBOL(_find_next_zero_bit_be);
 EXPORT_SYMBOL(_find_first_bit_be);
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index d422529..f8a2bd3 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,28 +1,33 @@
-
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
+#if __LINUX_ARM_ARCH__ >= 6
 	.macro	bitop, instr
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	and	r3, r0, #7		@ Get bit offset
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	\instr	r2, r2, r3
-	strexb	r0, r2, [r1]
+	strex	r0, r2, [r1]
 	cmp	r0, #0
 	bne	1b
 	mov	pc, lr
 	.endm
 
 	.macro	testop, instr, store
-	and	r3, r0, #7		@ Get bit offset
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3		@ create mask
 	smp_dmb
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	ands	r0, r2, r3		@ save old value of bit
-	\instr	r2, r2, r3			@ toggle bit
-	strexb	ip, r2, [r1]
+	\instr	r2, r2, r3		@ toggle bit
+	strex	ip, r2, [r1]
 	cmp	ip, #0
 	bne	1b
 	smp_dmb
@@ -32,13 +37,16 @@
 	.endm
 #else
 	.macro	bitop, instr
-	and	r2, r0, #7
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r2, r0, #31
+	mov	r0, r0, lsr #5
 	mov	r3, #1
 	mov	r3, r3, lsl r2
 	save_and_disable_irqs ip
-	ldrb	r2, [r1, r0, lsr #3]
+	ldr	r2, [r1, r0, lsl #2]
 	\instr	r2, r2, r3
-	strb	r2, [r1, r0, lsr #3]
+	str	r2, [r1, r0, lsl #2]
 	restore_irqs ip
 	mov	pc, lr
 	.endm
@@ -52,11 +60,13 @@
  * to avoid dirtying the data cache.
  */
 	.macro	testop, instr, store
-	add	r1, r1, r0, lsr #3
-	and	r3, r0, #7
-	mov	r0, #1
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r3, r0, #31
+	mov	r0, r0, lsr #5
 	save_and_disable_irqs ip
-	ldrb	r2, [r1]
+	ldr	r2, [r1, r0, lsl #2]!
+	mov	r0, #1
 	tst	r2, r0, lsl r3
 	\instr	r2, r2, r0, lsl r3
 	\store	r2, [r1]
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 80f3115..68ed5b6 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -12,12 +12,6 @@
 #include "bitops.h"
                 .text
 
-/* Purpose  : Function to change a bit
- * Prototype: int change_bit(int bit, void *addr)
- */
-ENTRY(_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_change_bit_le)
+ENTRY(_change_bit)
 	bitop	eor
-ENDPROC(_change_bit_be)
-ENDPROC(_change_bit_le)
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 1a63e43..4c04c3b 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
                 .text
 
-/*
- * Purpose  : Function to clear a bit
- * Prototype: int clear_bit(int bit, void *addr)
- */
-ENTRY(_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_clear_bit_le)
+ENTRY(_clear_bit)
 	bitop	bic
-ENDPROC(_clear_bit_be)
-ENDPROC(_clear_bit_le)
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 64f6bc1..7edd605 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -22,6 +22,8 @@
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
 ENTRY(_find_first_zero_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
@@ -43,6 +45,8 @@ ENDPROC(_find_first_zero_bit_le)
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
 ENTRY(_find_next_zero_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -63,6 +67,8 @@ ENDPROC(_find_next_zero_bit_le)
  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  */
 ENTRY(_find_first_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
@@ -84,6 +90,8 @@ ENDPROC(_find_first_bit_le)
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
 ENTRY(_find_next_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -101,6 +109,8 @@ ENDPROC(_find_next_bit_le)
 #ifdef __ARMEB__
 
 ENTRY(_find_first_zero_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3f
 		mov	r2, #0
@@ -118,6 +128,8 @@ ENTRY(_find_first_zero_bit_be)
 ENDPROC(_find_first_zero_bit_be)
 
 ENTRY(_find_next_zero_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -135,6 +147,8 @@ ENTRY(_find_next_zero_bit_be)
 ENDPROC(_find_next_zero_bit_be)
 
 ENTRY(_find_first_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3f
 		mov	r2, #0
@@ -152,6 +166,8 @@ ENTRY(_find_first_bit_be)
 ENDPROC(_find_first_bit_be)
 
 ENTRY(_find_next_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 1dd7176..bbee5c6 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
 		.text
 
-/*
- * Purpose  : Function to set a bit
- * Prototype: int set_bit(int bit, void *addr)
- */
-ENTRY(_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_set_bit_le)
+ENTRY(_set_bit)
 	bitop	orr
-ENDPROC(_set_bit_be)
-ENDPROC(_set_bit_le)
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index 5c98dc5..15a4d43 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_change_bit_le)
-	testop	eor, strb
-ENDPROC(_test_and_change_bit_be)
-ENDPROC(_test_and_change_bit_le)
+ENTRY(_test_and_change_bit)
+	testop	eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 543d709..521b66b 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_clear_bit_le)
-	testop	bicne, strneb
-ENDPROC(_test_and_clear_bit_be)
-ENDPROC(_test_and_clear_bit_le)
+ENTRY(_test_and_clear_bit)
+	testop	bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 0b3f390..1c98cc2 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_set_bit_le)
-	testop	orreq, streqb
-ENDPROC(_test_and_set_bit_be)
-ENDPROC(_test_and_set_bit_le)
+ENTRY(_test_and_set_bit)
+	testop	orreq, streq
+ENDPROC(_test_and_set_bit)

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-16 18:15   ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-16 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
> I strongly suggest you ensure you have a copy of your filesystems before
> trying this patch.
> 
> The patch below switches the bitops to use word loads/stores rather than
> byte operations - so that we can avoid using the ldrexb/strexb instructions
> which are only supported from ARMv6k and up.
> 
> The current bitops prevent a single kernel covering ARMv6 and ARMv7
> architectures without the resulting kernel being unsafe on SMP.  As
> ldrex/strex is supported from ARMv6 upwards, but ldrexb/strexb is not,
> switch these functions to use the word-based loads/stores.
> 
> As our bitops functions have been tolerant of misaligned pointers, they
> now include a check which will do a NULL pointer store in the event that
> they're passed a non-aligned pointers: ldrex/strex can't cope with such
> things.
> 
> I've verified in userspace that these give the same results on LE setups
> as our existing implementation - that doesn't mean these aren't buggy, it
> just means they appear to behave the same for the testing I've done.  BE
> is completely untested (I don't have any ARM BE setups.)
> 
> Someone who uses BE setups needs to check that filesystem images (for
> minix and ext2/ext3) which worked prior to this patch continue to work
> after these patches.
> 
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Revised patch - the previous one was slightly buggered for BE.  We also
don't need to touch the findbit operations at all, so that part has been
dropped.

This includes a patch by Akinobu Mita ("arm: introduce little-endian
bitops", v4).

 arch/arm/include/asm/bitops.h |  114 +++++++++++++++++++++--------------------
 arch/arm/kernel/armksyms.c    |   18 ++----
 arch/arm/lib/bitops.h         |   46 ++++++++++-------
 arch/arm/lib/changebit.S      |   10 +---
 arch/arm/lib/clearbit.S       |   11 +---
 arch/arm/lib/findbit.S        |   16 ++++++
 arch/arm/lib/setbit.S         |   11 +---
 arch/arm/lib/testchangebit.S  |    9 +--
 arch/arm/lib/testclearbit.S   |    9 +--
 arch/arm/lib/testsetbit.S     |    9 +--
 10 files changed, 124 insertions(+), 129 deletions(-)

diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 338ff19..1e8c366 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,30 +149,28 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  */
 
 /*
+ * Native endian assembly bitops.  nr = 0 -> word 0 bit 0.
+ */
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+
+/*
  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
  */
-extern void _set_bit_le(int nr, volatile unsigned long * p);
-extern void _clear_bit_le(int nr, volatile unsigned long * p);
-extern void _change_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(const void * p, unsigned size);
-extern int _find_next_zero_bit_le(const void * p, int size, int offset);
+extern int _find_first_zero_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_zero_bit_le(const unsigned long *p, int size, int offset);
 extern int _find_first_bit_le(const unsigned long *p, unsigned size);
 extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
 /*
  * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
  */
-extern void _set_bit_be(int nr, volatile unsigned long * p);
-extern void _clear_bit_be(int nr, volatile unsigned long * p);
-extern void _change_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_be(const void * p, unsigned size);
-extern int _find_next_zero_bit_be(const void * p, int size, int offset);
+extern int _find_first_zero_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_zero_bit_be(const unsigned long *p, int size, int offset);
 extern int _find_first_bit_be(const unsigned long *p, unsigned size);
 extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 
@@ -180,33 +178,26 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 /*
  * The __* form of bitops are non-atomic and may be reordered.
  */
-#define	ATOMIC_BITOP_LE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_le(nr,p))
-
-#define	ATOMIC_BITOP_BE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_be(nr,p))
+#define ATOMIC_BITOP(name,nr,p)			\
+	(__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
 #else
-#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
-#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
+#define ATOMIC_BITOP(name,nr,p)		_##name(nr,p)
 #endif
 
-#define NONATOMIC_BITOP(name,nr,p)		\
-	(____nonatomic_##name(nr, p))
+/*
+ * Native endian atomic definitions.
+ */
+#define set_bit(nr,p)			ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p)			ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p)		ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p)		ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p)	ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p)	ATOMIC_BITOP(test_and_change_bit,nr,p)
 
 #ifndef __ARMEB__
 /*
  * These are the little endian, atomic definitions.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_LE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_LE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
 #define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
 #define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
 #define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
@@ -215,16 +206,9 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 #define WORD_BITOFF_TO_LE(x)		((x))
 
 #else
-
 /*
  * These are the big endian, atomic definitions.
  */
-#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
-#define clear_bit(nr,p)			ATOMIC_BITOP_BE(clear_bit,nr,p)
-#define change_bit(nr,p)		ATOMIC_BITOP_BE(change_bit,nr,p)
-#define test_and_set_bit(nr,p)		ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p)	ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
 #define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)
 #define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_be(p,sz,off)
 #define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
@@ -303,41 +287,61 @@ static inline int fls(int x)
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
 
+#define __set_bit_le(nr, p)			\
+	__set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __clear_bit_le(nr, p)			\
+	__clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __test_and_set_bit_le(nr, p)			\
+		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_and_set_bit_le(nr, p)          \
+		test_and_set_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define __test_and_clear_bit_le(nr, p)			\
+		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_and_clear_bit_le(nr, p)	\
+		test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define test_bit_le(nr, p)			\
+		test_bit(WORD_BITOFF_TO_LE(nr), (p))
+#define find_first_zero_bit_le(p, sz)		\
+		_find_first_zero_bit_le(p, sz)
+#define find_next_zero_bit_le(p, sz, off)	\
+		_find_next_zero_bit_le(p, sz, off)
+#define find_next_bit_le(p, sz, off) \
+		_find_next_bit_le(p, sz, off)
 /*
  * Ext2 is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)			\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit_le(nr, (unsigned long *)(p))
 #define ext2_set_bit_atomic(lock,nr,p)          \
-                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_and_set_bit_le(nr, (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)			\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define ext2_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit_le(nr, (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		find_first_zero_bit_le((unsigned long *)(p), sz)
 #define ext2_find_next_zero_bit(p,sz,off)	\
-		_find_next_zero_bit_le(p,sz,off)
+		find_next_zero_bit_le((unsigned long *)(p), sz, off)
 #define ext2_find_next_bit(p, sz, off) \
-		_find_next_bit_le(p, sz, off)
+		find_next_bit_le((unsigned long *)(p), sz, off)
 
 /*
  * Minix is defined to use little-endian byte ordering.
  * These do not need to be atomic.
  */
 #define minix_set_bit(nr,p)			\
-		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__set_bit_le(nr, (unsigned long *)(p))
 #define minix_test_bit(nr,p)			\
-		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		test_bit_le(nr, (unsigned long *)(p))
 #define minix_test_and_set_bit(nr,p)		\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit_le(nr, (unsigned long *)(p))
 #define minix_test_and_clear_bit(nr,p)		\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_clear_bit_le(nr, (unsigned long *)(p))
 #define minix_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		find_first_zero_bit_le((unsigned long *)(p), sz)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index e5e1e53..d5d4185 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,24 +140,18 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
 #endif
 
 	/* bitops */
-EXPORT_SYMBOL(_set_bit_le);
-EXPORT_SYMBOL(_test_and_set_bit_le);
-EXPORT_SYMBOL(_clear_bit_le);
-EXPORT_SYMBOL(_test_and_clear_bit_le);
-EXPORT_SYMBOL(_change_bit_le);
-EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
 EXPORT_SYMBOL(_find_first_zero_bit_le);
 EXPORT_SYMBOL(_find_next_zero_bit_le);
 EXPORT_SYMBOL(_find_first_bit_le);
 EXPORT_SYMBOL(_find_next_bit_le);
 
 #ifdef __ARMEB__
-EXPORT_SYMBOL(_set_bit_be);
-EXPORT_SYMBOL(_test_and_set_bit_be);
-EXPORT_SYMBOL(_clear_bit_be);
-EXPORT_SYMBOL(_test_and_clear_bit_be);
-EXPORT_SYMBOL(_change_bit_be);
-EXPORT_SYMBOL(_test_and_change_bit_be);
 EXPORT_SYMBOL(_find_first_zero_bit_be);
 EXPORT_SYMBOL(_find_next_zero_bit_be);
 EXPORT_SYMBOL(_find_first_bit_be);
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index d422529..f8a2bd3 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,28 +1,33 @@
-
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
+#if __LINUX_ARM_ARCH__ >= 6
 	.macro	bitop, instr
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	and	r3, r0, #7		@ Get bit offset
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	\instr	r2, r2, r3
-	strexb	r0, r2, [r1]
+	strex	r0, r2, [r1]
 	cmp	r0, #0
 	bne	1b
 	mov	pc, lr
 	.endm
 
 	.macro	testop, instr, store
-	and	r3, r0, #7		@ Get bit offset
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
 	mov	r2, #1
-	add	r1, r1, r0, lsr #3	@ Get byte offset
+	and	r3, r0, #31		@ Get bit offset
+	mov	r0, r0, lsr #5
+	add	r1, r1, r0, lsl #2	@ Get word offset
 	mov	r3, r2, lsl r3		@ create mask
 	smp_dmb
-1:	ldrexb	r2, [r1]
+1:	ldrex	r2, [r1]
 	ands	r0, r2, r3		@ save old value of bit
-	\instr	r2, r2, r3			@ toggle bit
-	strexb	ip, r2, [r1]
+	\instr	r2, r2, r3		@ toggle bit
+	strex	ip, r2, [r1]
 	cmp	ip, #0
 	bne	1b
 	smp_dmb
@@ -32,13 +37,16 @@
 	.endm
 #else
 	.macro	bitop, instr
-	and	r2, r0, #7
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r2, r0, #31
+	mov	r0, r0, lsr #5
 	mov	r3, #1
 	mov	r3, r3, lsl r2
 	save_and_disable_irqs ip
-	ldrb	r2, [r1, r0, lsr #3]
+	ldr	r2, [r1, r0, lsl #2]
 	\instr	r2, r2, r3
-	strb	r2, [r1, r0, lsr #3]
+	str	r2, [r1, r0, lsl #2]
 	restore_irqs ip
 	mov	pc, lr
 	.endm
@@ -52,11 +60,13 @@
  * to avoid dirtying the data cache.
  */
 	.macro	testop, instr, store
-	add	r1, r1, r0, lsr #3
-	and	r3, r0, #7
-	mov	r0, #1
+	tst	r1, #3
+	strne	r1, [r1, -r1]		@ assert word-aligned
+	and	r3, r0, #31
+	mov	r0, r0, lsr #5
 	save_and_disable_irqs ip
-	ldrb	r2, [r1]
+	ldr	r2, [r1, r0, lsl #2]!
+	mov	r0, #1
 	tst	r2, r0, lsl r3
 	\instr	r2, r2, r0, lsl r3
 	\store	r2, [r1]
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 80f3115..68ed5b6 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -12,12 +12,6 @@
 #include "bitops.h"
                 .text
 
-/* Purpose  : Function to change a bit
- * Prototype: int change_bit(int bit, void *addr)
- */
-ENTRY(_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_change_bit_le)
+ENTRY(_change_bit)
 	bitop	eor
-ENDPROC(_change_bit_be)
-ENDPROC(_change_bit_le)
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 1a63e43..4c04c3b 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
                 .text
 
-/*
- * Purpose  : Function to clear a bit
- * Prototype: int clear_bit(int bit, void *addr)
- */
-ENTRY(_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_clear_bit_le)
+ENTRY(_clear_bit)
 	bitop	bic
-ENDPROC(_clear_bit_be)
-ENDPROC(_clear_bit_le)
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 64f6bc1..7edd605 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -22,6 +22,8 @@
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
 ENTRY(_find_first_zero_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
@@ -43,6 +45,8 @@ ENDPROC(_find_first_zero_bit_le)
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
 ENTRY(_find_next_zero_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -63,6 +67,8 @@ ENDPROC(_find_next_zero_bit_le)
  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  */
 ENTRY(_find_first_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
@@ -84,6 +90,8 @@ ENDPROC(_find_first_bit_le)
  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  */
 ENTRY(_find_next_bit_le)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -101,6 +109,8 @@ ENDPROC(_find_next_bit_le)
 #ifdef __ARMEB__
 
 ENTRY(_find_first_zero_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3f
 		mov	r2, #0
@@ -118,6 +128,8 @@ ENTRY(_find_first_zero_bit_be)
 ENDPROC(_find_first_zero_bit_be)
 
 ENTRY(_find_next_zero_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
@@ -135,6 +147,8 @@ ENTRY(_find_next_zero_bit_be)
 ENDPROC(_find_next_zero_bit_be)
 
 ENTRY(_find_first_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3f
 		mov	r2, #0
@@ -152,6 +166,8 @@ ENTRY(_find_first_bit_be)
 ENDPROC(_find_first_bit_be)
 
 ENTRY(_find_next_bit_be)
+		tst	r0, #3
+		strne	r0, [r0, -r0]		@ assert word-aligned
 		teq	r1, #0
 		beq	3b
 		ands	ip, r2, #7
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 1dd7176..bbee5c6 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -12,13 +12,6 @@
 #include "bitops.h"
 		.text
 
-/*
- * Purpose  : Function to set a bit
- * Prototype: int set_bit(int bit, void *addr)
- */
-ENTRY(_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_set_bit_le)
+ENTRY(_set_bit)
 	bitop	orr
-ENDPROC(_set_bit_be)
-ENDPROC(_set_bit_le)
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index 5c98dc5..15a4d43 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_change_bit_le)
-	testop	eor, strb
-ENDPROC(_test_and_change_bit_be)
-ENDPROC(_test_and_change_bit_le)
+ENTRY(_test_and_change_bit)
+	testop	eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 543d709..521b66b 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_clear_bit_le)
-	testop	bicne, strneb
-ENDPROC(_test_and_clear_bit_be)
-ENDPROC(_test_and_clear_bit_le)
+ENTRY(_test_and_clear_bit)
+	testop	bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 0b3f390..1c98cc2 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,9 +12,6 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit_be)
-		eor	r0, r0, #0x18		@ big endian byte ordering
-ENTRY(_test_and_set_bit_le)
-	testop	orreq, streqb
-ENDPROC(_test_and_set_bit_be)
-ENDPROC(_test_and_set_bit_le)
+ENTRY(_test_and_set_bit)
+	testop	orreq, streq
+ENDPROC(_test_and_set_bit)

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-16 12:19 ` Russell King - ARM Linux
@ 2011-01-17  9:46   ` Jamie Iles
  -1 siblings, 0 replies; 20+ messages in thread
From: Jamie Iles @ 2011-01-17  9:46 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
> I strongly suggest you ensure you have a copy of your filesystems before
> trying this patch.
> 
> The patch below switches the bitops to use word loads/stores rather than
> byte operations - so that we can avoid using the ldrexb/strexb instructions
> which are only supported from ARMv6k and up.
[...]
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.

Hi Russell,

I've tested these on my picoxcell board (ARMv6K UP LE) with UBIFS, JFFS2 
and NFS all mounted rw and haven't seen any problems.  Our platforms 
aren't particulary FS intensive so I'll keep these patches applied to 
give them a bit more time.

Tested-by: Jamie Iles <jamie@jamieiles.com>

Jamie

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-17  9:46   ` Jamie Iles
  0 siblings, 0 replies; 20+ messages in thread
From: Jamie Iles @ 2011-01-17  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> XXX WARNING: bitops are used heavily by filesystem code: there be dragons XXX
> I strongly suggest you ensure you have a copy of your filesystems before
> trying this patch.
> 
> The patch below switches the bitops to use word loads/stores rather than
> byte operations - so that we can avoid using the ldrexb/strexb instructions
> which are only supported from ARMv6k and up.
[...]
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.

Hi Russell,

I've tested these on my picoxcell board (ARMv6K UP LE) with UBIFS, JFFS2 
and NFS all mounted rw and haven't seen any problems.  Our platforms 
aren't particulary FS intensive so I'll keep these patches applied to 
give them a bit more time.

Tested-by: Jamie Iles <jamie@jamieiles.com>

Jamie

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-16 12:19 ` Russell King - ARM Linux
@ 2011-01-17 10:08   ` Uwe Kleine-König
  -1 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-17 10:08 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

Hello Russell,

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.
You could make life a bit easier (at least for us at Pengutronix,
probably more) if you had a branch with a defined name for patches like
these.  We could add that to our daily test then.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-17 10:08   ` Uwe Kleine-König
  0 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-17 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Russell,

On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> This does need a fair amount of testing before it can be merged, so I'd
> like to see a number of Tested-by's against this patch.  Please also
> indicate whether you tested on LE or BE or both, which filesystems, and
> whether they were read-only mounted or read-write mounted.
You could make life a bit easier (at least for us at Pengutronix,
probably more) if you had a branch with a defined name for patches like
these.  We could add that to our daily test then.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-17 10:08   ` Uwe Kleine-König
@ 2011-01-17 10:46     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-17 10:46 UTC (permalink / raw)
  To: Uwe Kleine-König; +Cc: linux-arm-kernel, linux-omap

On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-König wrote:
> Hello Russell,
> 
> On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > This does need a fair amount of testing before it can be merged, so I'd
> > like to see a number of Tested-by's against this patch.  Please also
> > indicate whether you tested on LE or BE or both, which filesystems, and
> > whether they were read-only mounted or read-write mounted.
> You could make life a bit easier (at least for us at Pengutronix,
> probably more) if you had a branch with a defined name for patches like
> these.  We could add that to our daily test then.

No, because then it's not possible to properly tie down what has been
tested and what hasn't.

The advantage of emailed patches is that when people reply to them, you
have a better idea that the patch to which they're replying to is the
one they tested.

Such as in this case where the follow-up patch hasn't received any
replies, and so I can't add the one received tested-by to the follow-up
patch.  With the git approach, I wouldn't know what was tested unless
you included the commit IDs each time.

And let's face it - if it was tested daily, are you going to go through
the hastle of digging out the commit IDs and emailing each day to say
what was tested?  That sounds to me like a _lot_ more work than testing
the occasional emailed patch.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-17 10:46     ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-17 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-K?nig wrote:
> Hello Russell,
> 
> On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > This does need a fair amount of testing before it can be merged, so I'd
> > like to see a number of Tested-by's against this patch.  Please also
> > indicate whether you tested on LE or BE or both, which filesystems, and
> > whether they were read-only mounted or read-write mounted.
> You could make life a bit easier (at least for us at Pengutronix,
> probably more) if you had a branch with a defined name for patches like
> these.  We could add that to our daily test then.

No, because then it's not possible to properly tie down what has been
tested and what hasn't.

The advantage of emailed patches is that when people reply to them, you
have a better idea that the patch to which they're replying to is the
one they tested.

Such as in this case where the follow-up patch hasn't received any
replies, and so I can't add the one received tested-by to the follow-up
patch.  With the git approach, I wouldn't know what was tested unless
you included the commit IDs each time.

And let's face it - if it was tested daily, are you going to go through
the hastle of digging out the commit IDs and emailing each day to say
what was tested?  That sounds to me like a _lot_ more work than testing
the occasional emailed patch.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-16 18:15   ` Russell King - ARM Linux
@ 2011-01-17 11:03     ` Jamie Iles
  -1 siblings, 0 replies; 20+ messages in thread
From: Jamie Iles @ 2011-01-17 11:03 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

On Sun, Jan 16, 2011 at 06:15:51PM +0000, Russell King - ARM Linux wrote:
> Revised patch - the previous one was slightly buggered for BE.  We also
> don't need to touch the findbit operations at all, so that part has been
> dropped.
> 
> This includes a patch by Akinobu Mita ("arm: introduce little-endian
> bitops", v4).

Oops, I hit reply to the wrong patch before.  Sorry!

Tested-by: Jamie Iles <jamie@jamieiles.com>

Jamie

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-17 11:03     ` Jamie Iles
  0 siblings, 0 replies; 20+ messages in thread
From: Jamie Iles @ 2011-01-17 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jan 16, 2011 at 06:15:51PM +0000, Russell King - ARM Linux wrote:
> Revised patch - the previous one was slightly buggered for BE.  We also
> don't need to touch the findbit operations at all, so that part has been
> dropped.
> 
> This includes a patch by Akinobu Mita ("arm: introduce little-endian
> bitops", v4).

Oops, I hit reply to the wrong patch before.  Sorry!

Tested-by: Jamie Iles <jamie@jamieiles.com>

Jamie

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-17 10:46     ` Russell King - ARM Linux
@ 2011-01-18 15:32       ` Uwe Kleine-König
  -1 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-18 15:32 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

Hi Russell,

On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-König wrote:
> > On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > > This does need a fair amount of testing before it can be merged, so I'd
> > > like to see a number of Tested-by's against this patch.  Please also
> > > indicate whether you tested on LE or BE or both, which filesystems, and
> > > whether they were read-only mounted or read-write mounted.
> > You could make life a bit easier (at least for us at Pengutronix,
> > probably more) if you had a branch with a defined name for patches like
> > these.  We could add that to our daily test then.
> 
> No, because then it's not possible to properly tie down what has been
> tested and what hasn't.
> 
> The advantage of emailed patches is that when people reply to them, you
> have a better idea that the patch to which they're replying to is the
> one they tested.
> 
> Such as in this case where the follow-up patch hasn't received any
> replies, and so I can't add the one received tested-by to the follow-up
> patch.  With the git approach, I wouldn't know what was tested unless
> you included the commit IDs each time.
> 
> And let's face it - if it was tested daily, are you going to go through
> the hastle of digging out the commit IDs and emailing each day to say
> what was tested?  That sounds to me like a _lot_ more work than testing
> the occasional emailed patch.
I maybe wouldn't report each success, I would report if my test fails.
You can consider this more or less valuable. Still I think given the
ease this could be done it's worth it.

That's how linux-next works, too.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-18 15:32       ` Uwe Kleine-König
  0 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-18 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-K?nig wrote:
> > On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > > This does need a fair amount of testing before it can be merged, so I'd
> > > like to see a number of Tested-by's against this patch.  Please also
> > > indicate whether you tested on LE or BE or both, which filesystems, and
> > > whether they were read-only mounted or read-write mounted.
> > You could make life a bit easier (at least for us at Pengutronix,
> > probably more) if you had a branch with a defined name for patches like
> > these.  We could add that to our daily test then.
> 
> No, because then it's not possible to properly tie down what has been
> tested and what hasn't.
> 
> The advantage of emailed patches is that when people reply to them, you
> have a better idea that the patch to which they're replying to is the
> one they tested.
> 
> Such as in this case where the follow-up patch hasn't received any
> replies, and so I can't add the one received tested-by to the follow-up
> patch.  With the git approach, I wouldn't know what was tested unless
> you included the commit IDs each time.
> 
> And let's face it - if it was tested daily, are you going to go through
> the hastle of digging out the commit IDs and emailing each day to say
> what was tested?  That sounds to me like a _lot_ more work than testing
> the occasional emailed patch.
I maybe wouldn't report each success, I would report if my test fails.
You can consider this more or less valuable. Still I think given the
ease this could be done it's worth it.

That's how linux-next works, too.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-18 15:32       ` Uwe Kleine-König
@ 2011-01-18 15:43         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-18 15:43 UTC (permalink / raw)
  To: Uwe Kleine-König; +Cc: linux-arm-kernel, linux-omap

On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-König wrote:
> Hi Russell,
> 
> On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> > On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-König wrote:
> > > On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > > > This does need a fair amount of testing before it can be merged, so I'd
> > > > like to see a number of Tested-by's against this patch.  Please also
> > > > indicate whether you tested on LE or BE or both, which filesystems, and
> > > > whether they were read-only mounted or read-write mounted.
> > > You could make life a bit easier (at least for us at Pengutronix,
> > > probably more) if you had a branch with a defined name for patches like
> > > these.  We could add that to our daily test then.
> > 
> > No, because then it's not possible to properly tie down what has been
> > tested and what hasn't.
> > 
> > The advantage of emailed patches is that when people reply to them, you
> > have a better idea that the patch to which they're replying to is the
> > one they tested.
> > 
> > Such as in this case where the follow-up patch hasn't received any
> > replies, and so I can't add the one received tested-by to the follow-up
> > patch.  With the git approach, I wouldn't know what was tested unless
> > you included the commit IDs each time.
> > 
> > And let's face it - if it was tested daily, are you going to go through
> > the hastle of digging out the commit IDs and emailing each day to say
> > what was tested?  That sounds to me like a _lot_ more work than testing
> > the occasional emailed patch.
> I maybe wouldn't report each success, I would report if my test fails.
> You can consider this more or less valuable. Still I think given the
> ease this could be done it's worth it.
> 
> That's how linux-next works, too.

And linux-next is an extremely poor test of whether a patch is correct
or not.  It's a good test of whether there's any merge issues between
trees and that's all.

The point of posting patches to mailing lists is to get them:
(a) reviewed, and add Reviewed-by/Acked-by attributes to them
(b) get them tested by other people and successes reported back,
    as well as failures.

You don't get (b) from any automated test system, and (b) is what I'm
after.  It's completely pointless to throw them into some sort of branch
which gets automatically tested if there's no positive feedback coming
from such a test.

It gives nothing more than just throwing them at linux-next and listening
for the resounding silence.  I personally have never had anyone say "I
tested your patch X in linux-next and it really worked for me".  It just
doesn't happen.  And so it's useless as a system for testing the quality
of patches.

I have had the extremely _rare_ report that something has broken in
linux-next, but on the whole those virtually never happen even when there
has been breakage.  See the recent breakage of OMAP with the sched_clock()
fixes, which had been sitting in linux-next for about a week with no one
noticing.

So, no, I give zero value to automatic test systems as a means to ascertain
the quality of patches.  Their *only* use is as a tool to check whether
a particular combination of patches builds.  Nothing more.

I will continue to mail out patches which I want people to test and give
feedback on, because that is the _only_ way to do it.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-18 15:43         ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-18 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-K?nig wrote:
> Hi Russell,
> 
> On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> > On Mon, Jan 17, 2011 at 11:08:57AM +0100, Uwe Kleine-K?nig wrote:
> > > On Sun, Jan 16, 2011 at 12:19:11PM +0000, Russell King - ARM Linux wrote:
> > > > This does need a fair amount of testing before it can be merged, so I'd
> > > > like to see a number of Tested-by's against this patch.  Please also
> > > > indicate whether you tested on LE or BE or both, which filesystems, and
> > > > whether they were read-only mounted or read-write mounted.
> > > You could make life a bit easier (at least for us at Pengutronix,
> > > probably more) if you had a branch with a defined name for patches like
> > > these.  We could add that to our daily test then.
> > 
> > No, because then it's not possible to properly tie down what has been
> > tested and what hasn't.
> > 
> > The advantage of emailed patches is that when people reply to them, you
> > have a better idea that the patch to which they're replying to is the
> > one they tested.
> > 
> > Such as in this case where the follow-up patch hasn't received any
> > replies, and so I can't add the one received tested-by to the follow-up
> > patch.  With the git approach, I wouldn't know what was tested unless
> > you included the commit IDs each time.
> > 
> > And let's face it - if it was tested daily, are you going to go through
> > the hastle of digging out the commit IDs and emailing each day to say
> > what was tested?  That sounds to me like a _lot_ more work than testing
> > the occasional emailed patch.
> I maybe wouldn't report each success, I would report if my test fails.
> You can consider this more or less valuable. Still I think given the
> ease this could be done it's worth it.
> 
> That's how linux-next works, too.

And linux-next is an extremely poor test of whether a patch is correct
or not.  It's a good test of whether there's any merge issues between
trees and that's all.

The point of posting patches to mailing lists is to get them:
(a) reviewed, and add Reviewed-by/Acked-by attributes to them
(b) get them tested by other people and successes reported back,
    as well as failures.

You don't get (b) from any automated test system, and (b) is what I'm
after.  It's completely pointless to throw them into some sort of branch
which gets automatically tested if there's no positive feedback coming
from such a test.

It gives nothing more than just throwing them at linux-next and listening
for the resounding silence.  I personally have never had anyone say "I
tested your patch X in linux-next and it really worked for me".  It just
doesn't happen.  And so it's useless as a system for testing the quality
of patches.

I have had the extremely _rare_ report that something has broken in
linux-next, but on the whole those virtually never happen even when there
has been breakage.  See the recent breakage of OMAP with the sched_clock()
fixes, which had been sitting in linux-next for about a week with no one
noticing.

So, no, I give zero value to automatic test systems as a means to ascertain
the quality of patches.  Their *only* use is as a tool to check whether
a particular combination of patches builds.  Nothing more.

I will continue to mail out patches which I want people to test and give
feedback on, because that is the _only_ way to do it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-18 15:43         ` Russell King - ARM Linux
@ 2011-01-18 15:58           ` Uwe Kleine-König
  -1 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-18 15:58 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

Hello Russell,

On Tue, Jan 18, 2011 at 03:43:44PM +0000, Russell King - ARM Linux wrote:
> On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-König wrote:
> > On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> I will continue to mail out patches which I want people to test and give
> feedback on, because that is the _only_ way to do it.
Note that I didn't suggest to stop sending out patches and collecting
the acks and tested-bys there.  The automated tests are just a different
test.

And IMHO it's not harder to reply with a git commit-id, but it makes it
more likely that a reply to a wrong mail is detected.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-18 15:58           ` Uwe Kleine-König
  0 siblings, 0 replies; 20+ messages in thread
From: Uwe Kleine-König @ 2011-01-18 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Russell,

On Tue, Jan 18, 2011 at 03:43:44PM +0000, Russell King - ARM Linux wrote:
> On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-K?nig wrote:
> > On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> I will continue to mail out patches which I want people to test and give
> feedback on, because that is the _only_ way to do it.
Note that I didn't suggest to stop sending out patches and collecting
the acks and tested-bys there.  The automated tests are just a different
test.

And IMHO it's not harder to reply with a git commit-id, but it makes it
more likely that a reply to a wrong mail is detected.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC+CFT] Use word operations in bitops
  2011-01-18 15:58           ` Uwe Kleine-König
@ 2011-01-18 16:28             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-18 16:28 UTC (permalink / raw)
  To: Uwe Kleine-König; +Cc: linux-arm-kernel, linux-omap

On Tue, Jan 18, 2011 at 04:58:51PM +0100, Uwe Kleine-König wrote:
> Hello Russell,
> 
> On Tue, Jan 18, 2011 at 03:43:44PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-König wrote:
> > > On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> > I will continue to mail out patches which I want people to test and give
> > feedback on, because that is the _only_ way to do it.
> Note that I didn't suggest to stop sending out patches and collecting
> the acks and tested-bys there.  The automated tests are just a different
> test.
> 
> And IMHO it's not harder to reply with a git commit-id, but it makes it
> more likely that a reply to a wrong mail is detected.

No.  Take a moment and think.

Two people pull the commits one evening.  One gets in during GMT morning,
checks their tests, and reports "git commit X passed, have this Tested-by".
So, their tested-by is added to the commit, which changes the git ID to
Y.

Second person gets in during GMT afternoon, and reports "git commit X
passed."  Now instead of looking in the current branch, I'd have to
cross-reference it back to what was originally there, check that's
what they actually meant, look that up in the new branch, and apply
their tested-by to that instead.

More complicated means more things to go wrong.  No thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC+CFT] Use word operations in bitops
@ 2011-01-18 16:28             ` Russell King - ARM Linux
  0 siblings, 0 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2011-01-18 16:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 18, 2011 at 04:58:51PM +0100, Uwe Kleine-K?nig wrote:
> Hello Russell,
> 
> On Tue, Jan 18, 2011 at 03:43:44PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Jan 18, 2011 at 04:32:57PM +0100, Uwe Kleine-K?nig wrote:
> > > On Mon, Jan 17, 2011 at 10:46:18AM +0000, Russell King - ARM Linux wrote:
> > I will continue to mail out patches which I want people to test and give
> > feedback on, because that is the _only_ way to do it.
> Note that I didn't suggest to stop sending out patches and collecting
> the acks and tested-bys there.  The automated tests are just a different
> test.
> 
> And IMHO it's not harder to reply with a git commit-id, but it makes it
> more likely that a reply to a wrong mail is detected.

No.  Take a moment and think.

Two people pull the commits one evening.  One gets in during GMT morning,
checks their tests, and reports "git commit X passed, have this Tested-by".
So, their tested-by is added to the commit, which changes the git ID to
Y.

Second person gets in during GMT afternoon, and reports "git commit X
passed."  Now instead of looking in the current branch, I'd have to
cross-reference it back to what was originally there, check that's
what they actually meant, look that up in the new branch, and apply
their tested-by to that instead.

More complicated means more things to go wrong.  No thank you.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-01-18 16:30 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-16 12:19 [RFC+CFT] Use word operations in bitops Russell King - ARM Linux
2011-01-16 12:19 ` Russell King - ARM Linux
2011-01-16 18:15 ` Russell King - ARM Linux
2011-01-16 18:15   ` Russell King - ARM Linux
2011-01-17 11:03   ` Jamie Iles
2011-01-17 11:03     ` Jamie Iles
2011-01-17  9:46 ` Jamie Iles
2011-01-17  9:46   ` Jamie Iles
2011-01-17 10:08 ` Uwe Kleine-König
2011-01-17 10:08   ` Uwe Kleine-König
2011-01-17 10:46   ` Russell King - ARM Linux
2011-01-17 10:46     ` Russell King - ARM Linux
2011-01-18 15:32     ` Uwe Kleine-König
2011-01-18 15:32       ` Uwe Kleine-König
2011-01-18 15:43       ` Russell King - ARM Linux
2011-01-18 15:43         ` Russell King - ARM Linux
2011-01-18 15:58         ` Uwe Kleine-König
2011-01-18 15:58           ` Uwe Kleine-König
2011-01-18 16:28           ` Russell King - ARM Linux
2011-01-18 16:28             ` Russell King - ARM Linux

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.