summaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/spinlock_types.h
diff options
context:
space:
mode:
authorDavid Daney2010-02-04 20:31:49 +0100
committerRalf Baechle2010-02-27 12:53:42 +0100
commit500c2e1fdbcc2b273bd4c695a9b8ac8196f61614 (patch)
treef24c80f609a739beed194fd5c66abf9bc48ce0d6 /arch/mips/include/asm/spinlock_types.h
parentMIPS: Alchemy: devboard PM needs to save CPLD registers. (diff)
downloadkernel-qcow2-linux-500c2e1fdbcc2b273bd4c695a9b8ac8196f61614.tar.gz
kernel-qcow2-linux-500c2e1fdbcc2b273bd4c695a9b8ac8196f61614.tar.xz
kernel-qcow2-linux-500c2e1fdbcc2b273bd4c695a9b8ac8196f61614.zip
MIPS: Optimize spinlocks.
The current locking mechanism uses a ll/sc sequence to release a spinlock. This is slower than a wmb() followed by a store to unlock. The branching forward to .subsection 2 on sc failure slows down the contended case. So we get rid of that part too. Since we are now working on naturally aligned u16 values, we can get rid of a masking operation as the LHU already does the right thing. The ANDI are reversed for better scheduling on multi-issue CPUs On a 12 CPU 750MHz Octeon cn5750 this patch improves ipv4 UDP packet forwarding rates from 3.58*10^6 PPS to 3.99*10^6 PPS, or about 11%. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/937/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/spinlock_types.h')
-rw-r--r--arch/mips/include/asm/spinlock_types.h24
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h
index ee197c2f9c98..c52f36013a9d 100644
--- a/arch/mips/include/asm/spinlock_types.h
+++ b/arch/mips/include/asm/spinlock_types.h
@@ -5,16 +5,28 @@
# error "please don't include this file directly"
#endif
-typedef struct {
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+
+typedef union {
/*
- * bits 0..13: serving_now
- * bits 14 : junk data
- * bits 15..28: ticket
+ * bits 0..15 : serving_now
+ * bits 16..31 : ticket
*/
- unsigned int lock;
+ u32 lock;
+ struct {
+#ifdef __BIG_ENDIAN
+ u16 ticket;
+ u16 serving_now;
+#else
+ u16 serving_now;
+ u16 ticket;
+#endif
+ } h;
} arch_spinlock_t;
-#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED { .lock = 0 }
typedef struct {
volatile unsigned int lock;