Subject: kern/26689: VIA C3 cache info support is broken
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <mlelstv@serpens.de>
List: netbsd-bugs
Date: 08/17/2004 00:35:36
>Number:         26689
>Category:       kern
>Synopsis:       VIA C3 cache info support is broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 16 22:38:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Michael van Elst
>Release:        NetBSD 2.0G
>Organization:
	
>Environment:
	
	
System: NetBSD pussyfoot 2.0G NetBSD 2.0G (PUSSYFOOT) #7: Tue Aug 17 00:06:45 MEST 2004 src@pussyfoot:/sys/arch/i386/compile/PUSSYFOOT i386
Architecture: i386
Machine: i386
>Description:
When running a recent -current kernel on an EPIA-M 9000 board with 512MB
RAM, I experienced freezes when writing more than about 230MByte to disk.

In the frozen state I could only escape into ddb and see that the
running process was waiting in uvm_wait() and that the page daemon
was woken rapidly without actually freeing any pages.

I have tracked down this behaviour to the VIA C3 cache info support
that was included with sys/arch/x86/x86/cacheinfo.c version 1.5
and other related files.

The code interprets results from CPUID instructions in a way specific
to the VIA C3 Nehemiah core. On other VIA C3 CPUs this interpretation
produces bogus results for the Level2 cache information:

| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: "VIA C3 Ezra"
| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: I-cache 64 KB 32B/line 4-way, D-cache 64 KB 32B/line 4-way
| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: L2 cache 16 MB 32B/line disabled
|                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: ITLB 128 4 KB entries 8-way
| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: DTLB 128 4 KB entries 8-way
| Aug 15 20:04:24 pussyfoot /netbsd: cpu0: 4097 page colors

The correct data for the L2 cache is: 64KB 32B/line 4-way

The number of colors is derived from the cache data..

I don't know how this causes the described freeze, maybe our VM
code can't handle 4097 colors ?

>How-To-Repeat:
Try to run a recent kernel on a EPIA-M 9000 board or any other VIA C3
board that does not use a Nehemiah core.

>Fix:
Here is a patch that interprets the Level2 cache information correctly
for VIA C3 CPUs other than the Nehemiah.

Index: sys/arch/x86/x86/cacheinfo.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/cacheinfo.c,v
retrieving revision 1.5
diff -u -r1.5 cacheinfo.c
--- sys/arch/x86/x86/cacheinfo.c	8 Aug 2004 05:16:16 -0000	1.5
+++ sys/arch/x86/x86/cacheinfo.c	16 Aug 2004 22:13:11 -0000
@@ -318,9 +318,20 @@
 	CPUID(0x80000006, descs[0], descs[1], descs[2], descs[3]);
 
 	cai = &ci->ci_cinfo[CAI_L2CACHE];
-	cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
-	cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
-	cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
+	switch (model) {
+	case 9:
+		/* Nehemiah */
+		cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
+		cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
+		cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
+		break;
+	default:
+		/* Ezra and others */
+		cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
+		cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
+		cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
+		break;
+	}
 }
 
 void
Index: sys/arch/x86/include/cacheinfo.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/cacheinfo.h,v
retrieving revision 1.2
diff -u -r1.2 cacheinfo.h
--- sys/arch/x86/include/cacheinfo.h	8 Aug 2004 05:16:16 -0000	1.2
+++ sys/arch/x86/include/cacheinfo.h	16 Aug 2004 22:13:11 -0000
@@ -144,10 +144,16 @@
 #define	VIA_L1_EDX_IC_LPT(x)		 (((x) >> 8)  & 0xff)
 #define	VIA_L1_EDX_IC_LS(x)		 ( (x)        & 0xff)
 
-/* L2 Cache */
-#define	VIA_L2_ECX_C_SIZE(x)		((((x) >> 16) & 0xffff) * 1024)
-#define	VIA_L2_ECX_C_ASSOC(x)		 (((x) >> 12) & 0xf)
-#define	VIA_L2_ECX_C_LPT(x)		 (((x) >> 8)  & 0xf)
+/* L2 Cache (Ezra and other) */
+#define	VIA_L2_ECX_C_SIZE(x)		((((x) >> 24) & 0xff) * 1024)
+#define	VIA_L2_ECX_C_ASSOC(x)		 (((x) >> 16) & 0xff)
+#define	VIA_L2_ECX_C_LPT(x)		 (((x) >> 8)  & 0xff)
 #define	VIA_L2_ECX_C_LS(x)		 ( (x)        & 0xff)
 
+/* L2 Cache (Nehemiah) */
+#define	VIA_L2N_ECX_C_SIZE(x)		((((x) >> 16) & 0xffff) * 1024)
+#define	VIA_L2N_ECX_C_ASSOC(x)		 (((x) >> 12) & 0xf)
+#define	VIA_L2N_ECX_C_LPT(x)		 (((x) >> 8)  & 0xf)
+#define	VIA_L2N_ECX_C_LS(x)		 ( (x)        & 0xff)
+
 #endif /* _X86_CACHEINFO_H */

>Release-Note:
>Audit-Trail:
>Unformatted: