Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [patch] linux 2.4.17: An mb() rework
@ 2002-01-30 14:56 Maciej W. Rozycki
  2002-01-30 20:02 ` Jason Gunthorpe
  0 siblings, 1 reply; 17+ messages in thread
From: Maciej W. Rozycki @ 2002-01-30 14:56 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips, linux-mips

Hello,

 The current implementation of mb() and friends is broken.  It depends on
a model-specific behaviour of the R4000/R4400 CPU and does not guarantee
preserving the desired semantics over the whole MIPS family.  What's
worse, recently I've identified a case it doesn't work at all on an
R4400SC CPU -- values written to an i/o memory resource were not committed
to the device even after executing over 40 subsequent instructions. 

 Here is a patch that implements mb() in an "architecturally defined" way. 
Since "sync" acts as a reordering barrier and an uncached load cannot be
prefetched or postponed, this implementation assures a correct
serialization on every MIPS processor, regardless of its implementation
details. 

 For MIPS I CPUs, which do not support the "sync" instruction, a lone
uncached load is defined to provide a serialization itself, thus the
implementation is correct for these CPUs as well. 

 The patch looks more complicated than it should, but it's a part of a
wbflush() clean-up and a few of these helper submacros are really needed
(and others are defined for consistency).

 Tested successfully on an R3400 and an R4400SC CPU on DECstation systems. 

 If anyone has any comments, then please speak up.  Otherwise, Ralf,
please apply.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.17-20020111-mb-4
diff -up --recursive --new-file linux-mips-2.4.17-20020111.macro/arch/mips/config.in linux-mips-2.4.17-20020111/arch/mips/config.in
--- linux-mips-2.4.17-20020111.macro/arch/mips/config.in	Mon Jan  7 05:27:13 2002
+++ linux-mips-2.4.17-20020111/arch/mips/config.in	Sat Jan 26 02:35:35 2002
@@ -363,6 +363,12 @@ else
       fi
    fi
 fi
+if [ "$CONFIG_CPU_R3000" = "y" -o \
+     "$CONFIG_CPU_TX39XX" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_SYNC n
+else
+   define_bool CONFIG_CPU_HAS_SYNC y
+fi
 endmenu
 
 mainmenu_option next_comment
diff -up --recursive --new-file linux-mips-2.4.17-20020111.macro/include/asm-mips/system.h linux-mips-2.4.17-20020111/include/asm-mips/system.h
--- linux-mips-2.4.17-20020111.macro/include/asm-mips/system.h	Thu Dec 13 05:28:09 2001
+++ linux-mips-2.4.17-20020111/include/asm-mips/system.h	Wed Jan 30 02:17:18 2002
@@ -18,9 +18,12 @@
 
 #include <linux/config.h>
 #include <asm/sgidefs.h>
-#include <asm/ptrace.h>
+
 #include <linux/kernel.h>
 
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
 __asm__ (
 	".macro\t__sti\n\t"
 	".set\tpush\n\t"
@@ -170,27 +173,57 @@ extern void __global_restore_flags(unsig
 /*
  * These are probably defined overly paranoid ...
  */
+#ifdef CONFIG_CPU_HAS_SYNC
+#define __sync()	__asm__ __volatile__("sync" : : : "memory")
+#else
+#define __sync()	do { } while(0)
+#endif
+
+#define __fast_wmb()	do { } while(0)
+#define __fast_rmb()			\
+	__asm__ __volatile__(		\
+		".set	push\n\t"	\
+		".set	noreorder\n\t"	\
+		"lw	$0,%0\n\t"	\
+		"nop\n\t"		\
+		".set	pop"		\
+		: /* no output */	\
+		: "m" (*(int *)KSEG1)	\
+		: "memory")
+#define __fast_mb()	__fast_rmb()
+
+#define fast_wmb()			\
+	do {				\
+		__sync();		\
+		__fast_wmb();		\
+	} while (0)
+#define fast_rmb()			\
+	do {				\
+		__sync();		\
+		__fast_rmb();		\
+	} while (0)
+#define fast_mb()			\
+	do {				\
+		__sync();		\
+		__fast_mb();		\
+	} while (0)
+
 #ifdef CONFIG_CPU_HAS_WB
 
 #include <asm/wbflush.h>
-#define rmb()	do { } while(0)
-#define wmb()	wbflush()
-#define mb()	wbflush()
+#define wmb()		fast_wmb()
+#define rmb()				\
+	do {				\
+		__sync();		\
+		wbflush();		\
+	} while (0)
+#define mb()		rmb()
 
 #else /* CONFIG_CPU_HAS_WB  */
 
-#define mb()						\
-__asm__ __volatile__(					\
-	"# prevent instructions being moved around\n\t"	\
-	".set\tnoreorder\n\t"				\
-	"# 8 nops to fool the R4400 pipeline\n\t"	\
-	"nop;nop;nop;nop;nop;nop;nop;nop\n\t"		\
-	".set\treorder"					\
-	: /* no output */				\
-	: /* no input */				\
-	: "memory")
-#define rmb() mb()
-#define wmb() mb()
+#define wmb()		fast_wmb()
+#define rmb()		fast_rmb()
+#define mb()		fast_mb()
 
 #endif /* CONFIG_CPU_HAS_WB  */
 

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

end of thread, other threads:[~2002-02-05 10:33 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-01-30 14:56 [patch] linux 2.4.17: An mb() rework Maciej W. Rozycki
2002-01-30 20:02 ` Jason Gunthorpe
2002-01-31 12:17   ` Maciej W. Rozycki
2002-01-31 20:35     ` Jason Gunthorpe
2002-01-31 21:50       ` Maciej W. Rozycki
2002-02-01  6:44         ` Jason Gunthorpe
2002-02-01  8:55           ` Dominic Sweetman
2002-02-01 12:04             ` Maciej W. Rozycki
2002-02-01  9:52           ` Hartvig Ekner
2002-02-01  9:52             ` Hartvig Ekner
2002-02-01 12:01           ` Maciej W. Rozycki
2002-01-31 23:38       ` Alan Cox
2002-01-31 23:38         ` Alan Cox
2002-02-01 12:27         ` Maciej W. Rozycki
2002-02-02 12:09           ` Maciej W. Rozycki
2002-02-04 17:02     ` Ralf Baechle
2002-02-05 10:33       ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox