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>
