Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Nov 2009 12:02:39 +0100
From:      Giovanni Trematerra <giovanni.trematerra@gmail.com>
To:        FreeBSD Current <freebsd-current@freebsd.org>
Cc:        Attilio Rao <attilio@freebsd.org>, des@des.no
Subject:   [PATCH] AMD Opteron Rev. E hack
Message-ID:  <4e6cba830911050302k56bed35aj5ca9fa16379ab325@mail.gmail.com>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hi,
I have a quick and dirty patch to address the problem as discussed on
commit r198868 in svn-src-head@
I introduced BROKEN_OPTERON_E kernel option for i386/amd64 arch.
The patch isn't tested yet, I only successfully compiled on i386.
Can you let me know if the patch is on the right direction to resolve the issue?
style(9) tips are welcomed.

Thank you

--
Giovanni Trematerra

[-- Attachment #2 --]
diff -r 75d35d8e7fe1 sys/amd64/amd64/identcpu.c
--- a/sys/amd64/amd64/identcpu.c	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/amd64/amd64/identcpu.c	Thu Nov 05 12:42:35 2009 +0100
@@ -404,6 +404,10 @@
 
 	if (cpu_vendor_id == CPU_VENDOR_AMD)
 		print_AMD_info();
+#if defined(BROKEN_OPTERON_E)
+	else
+		printf("BROKEN_OPTERON_E option in your kernel is useless with your CPU\n");
+#endif
 }
 
 void
@@ -620,10 +624,17 @@
 	 */
 	if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 &&
 	    CPUID_TO_MODEL(cpu_id) <= 0x3f) {
+#if !defined(BROKEN_OPTERON_E)
 		printf("WARNING: This architecture revision has known SMP "
 		    "hardware bugs which may cause random instability\n");
-		printf("WARNING: For details see: "
-		    "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n");
+#else
+		printf("WARNING: options BROKEN_OPTERON_E is in your kernel. "
+				"Expect performance penalties\n");
+	else
+
+		printf("WARNING: options BROKEN_OPTERON_E is useless with your CPU."
+				"Expect performance penalties\n");
+#endif
 	}
 }
 
diff -r 75d35d8e7fe1 sys/amd64/include/atomic.h
--- a/sys/amd64/include/atomic.h	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/amd64/include/atomic.h	Thu Nov 05 12:42:35 2009 +0100
@@ -36,6 +36,14 @@
 #define	wmb()	__asm __volatile("sfence;" : : : "memory")
 #define	rmb()	__asm __volatile("lfence;" : : : "memory")
 
+#include "opt_cpu.h"
+
+#if defined(BROKEN_OPTERON_E) && (defined(SMP) || !defined(_KERNEL))
+	#define OPTERON_E_HACK() rmb()
+#else
+	#define OPTERON_E_HACK()
+#endif
+
 /*
  * Various simple operations on memory, each of which is atomic in the
  * presence of interrupts and multiple processors.
@@ -147,6 +155,8 @@
 	  "m" (*dst)			/* 4 */
 	: "memory");
 
+	OPTERON_E_HACK();
+
 	return (res);
 }
 
@@ -168,6 +178,8 @@
 	  "m" (*dst)			/* 4 */
 	: "memory");
 
+	OPTERON_E_HACK();
+
 	return (res);
 }
 
@@ -251,6 +263,8 @@
 	: "m" (*p)			/* 2 */		\
 	: "memory");					\
 							\
+	OPTERON_E_HACK();		\
+							\
 	return (res);					\
 }							\
 							\
diff -r 75d35d8e7fe1 sys/conf/options.amd64
--- a/sys/conf/options.amd64	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/conf/options.amd64	Thu Nov 05 12:42:35 2009 +0100
@@ -49,6 +49,7 @@
 # EOF
 # -------------------------------
 HAMMER			opt_cpu.h
+BROKEN_OPTERON_E	opt_cpu.h
 PSM_HOOKRESUME		opt_psm.h
 PSM_RESETAFTERSUSPEND	opt_psm.h
 PSM_DEBUG		opt_psm.h
diff -r 75d35d8e7fe1 sys/conf/options.i386
--- a/sys/conf/options.i386	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/conf/options.i386	Thu Nov 05 12:42:35 2009 +0100
@@ -37,6 +37,7 @@
 TIMER_FREQ			opt_clock.h
 
 CPU_ATHLON_SSE_HACK		opt_cpu.h
+BROKEN_OPTERON_E	opt_cpu.h
 CPU_BLUELIGHTNING_3X		opt_cpu.h
 CPU_BLUELIGHTNING_FPU_OP_CACHE	opt_cpu.h
 CPU_BTB_EN			opt_cpu.h
diff -r 75d35d8e7fe1 sys/i386/i386/identcpu.c
--- a/sys/i386/i386/identcpu.c	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/i386/i386/identcpu.c	Thu Nov 05 12:42:35 2009 +0100
@@ -904,6 +904,11 @@
 		print_INTEL_info();
 	else if (cpu_vendor_id == CPU_VENDOR_TRANSMETA)
 		print_transmeta_info();
+
+#if defined(BROKEN_OPTERON_E)
+	if (cpu_vendor_id != CPU_VENDOR_AMD)
+		printf("BROKEN_OPTERON_E option in your kernel is useless with your CPU\n");
+#endif
 }
 
 void
@@ -1315,12 +1320,18 @@
 	 * model and family are identified.
 	 */
 	if (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x20 &&
-	    CPUID_TO_MODEL(cpu_id) <= 0x3f) {
+	    CPUID_TO_MODEL(cpu_id) <= 0x3f) 
+#if !defined(BROKEN_OPTERON_E)
 		printf("WARNING: This architecture revision has known SMP "
 		    "hardware bugs which may cause random instability\n");
-		printf("WARNING: For details see: "
-		    "http://bugzilla.kernel.org/show_bug.cgi?id=11305\n");
-	}
+#else
+		printf("WARNING: options BROKEN_OPTERON_E is in your kernel. "
+				"Expect performance penalties\n");
+	else
+
+		printf("WARNING: options BROKEN_OPTERON_E is useless with your CPU."
+				"Expect performance penalties\n");
+#endif
 }
 
 static void
diff -r 75d35d8e7fe1 sys/i386/include/atomic.h
--- a/sys/i386/include/atomic.h	Thu Nov 05 11:18:35 2009 +0100
+++ b/sys/i386/include/atomic.h	Thu Nov 05 12:42:35 2009 +0100
@@ -36,6 +36,14 @@
 #define	wmb()	__asm __volatile("lock; addl $0,(%%esp)" : : : "memory")
 #define	rmb()	__asm __volatile("lock; addl $0,(%%esp)" : : : "memory")
 
+#include "opt_cpu.h"
+
+#if defined(BROKEN_OPTERON_E) && (defined(SMP) || !defined(_KERNEL))
+	#define OPTERON_E_HACK() rmb()
+#else
+	#define OPTERON_E_HACK()
+#endif
+
 /*
  * Various simple operations on memory, each of which is atomic in the
  * presence of interrupts and multiple processors.
@@ -174,6 +182,8 @@
 	  "m" (*dst)			/* 4 */
 	: "memory");
 
+	OPTERON_E_HACK();
+
 	return (res);
 }
 
@@ -240,6 +250,8 @@
 	: "m" (*p)			/* 2 */		\
 	: "memory");					\
 							\
+	OPTERON_E_HACK();		\
+							\
 	return (res);					\
 }							\
 							\
help

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