Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 06 Feb 2006 20:29:35 -0800
From:      Cy Schubert <Cy.Schubert@komquats.com>
To:        freebsd-current@freebsd.org, netchild@freebsd.org
Subject:   Re: 7.0-CURRENT Hang
Message-ID:  <200602070429.k174TZ6v009581@cwsys.cwsent.com>

next in thread | raw e-mail | index | archive | help
Oops. In my haste I made a typo in my note. It should read when AL = 0x02. 
It should read as follows:

I identified the problem (see my original discussion about this in attached 
the email below).

On the Pentium P54C model (that's an old 120 MHz Pentium I use as a 4.x, 
5.x, and 7.x ports build testbed) the CPUID instruction when called with AL 
= 0x02, CPUID returns EAX = EBX = ECX = EDX = 0. The code fragment in 
identcpu.c below results in "rounds" becoming 0xffffffff.

	do_cpuid(0x2, regs);
	rounds = (regs[0] & 0xff) - 1;

The subsequent loop of the following will loop virtually for ever (it takes 
forever tor this machine to count down from 0xffffffff performing a very 
great many calls to get_INTEL_TLB in the process, virtually hanging the 
machine in the process.

	while (rounds > 0) {
		[... code ...]
		rounds--;
	}

To resolve my problem I cobbled up the following patch to identcpu.c:

--- sys/i386/i386/identcpu.c.orig	Thu Feb  2 04:44:09 2006
+++ sys/i386/i386/identcpu.c	Mon Feb  6 18:47:16 2006
@@ -1237,7 +1237,7 @@
 
 	do_cpuid(0x2, regs);
 
-	rounds = (regs[0] & 0xff) - 1;
+	rounds = (regs[0] & 0xff);
 
 	for (regnum = 0; regnum <= 3; ++regnum) {
 		if ((regs[regnum] & (1<<31)) == 0) {
@@ -1249,7 +1249,7 @@
 		}
 	}
 
-	while (rounds > 0) {
+	while (rounds > 1) {
 		do_cpuid(0x2, regs);
 
 		for (regnum = 0; regnum <= 3; ++regnum) {
@@ -1452,7 +1452,7 @@
 	u_int nwaycode;
 
 	do_cpuid(0x2, regs);
-	rounds = (regs[0] & 0xff) - 1;
+	rounds = (regs[0] & 0xff);
 
 	for (regnum = 0; regnum <= 3; ++regnum) {
 		if ((regs[regnum] & (1<<31)) == 0) {
@@ -1468,7 +1468,7 @@
 		}
 	}
 
-	while (rounds > 0) {
+	while (rounds > 1) {
 		do_cpuid(0x2, regs);
 
 		for (regnum = 0; regnum <= 3; ++regnum) {

It fixes the hang.



Cheers,
Cy Schubert <Cy.Schubert@komquats.com>
Web:  http://www.komquats.com and http://www.bcbodybuilder.com
FreeBSD UNIX:  <cy@FreeBSD.org>   Web:  http://www.FreeBSD.org
BC Government:  <Cy.Schubert@gov.bc.ca>

    "Lift long enough and I believe arrogance is replaced by
    humility and fear by courage and selfishness by generosity
    and rudeness by compassion and caring."
        -- Dave Draper





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