PERFORCE change 42827 for review

John Baldwin jhb at FreeBSD.org
Thu Nov 20 13:29:45 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=42827

Change 42827 by jhb at jhb_blue on 2003/11/20 13:29:25

	IFC @42825.

Affected files ...

.. //depot/projects/smpng/sys/amd64/conf/GENERIC#10 integrate
.. //depot/projects/smpng/sys/boot/i386/boot0/boot0.s#3 integrate
.. //depot/projects/smpng/sys/conf/files#96 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi.c#52 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_cpu.c#16 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pci_link.c#10 integrate
.. //depot/projects/smpng/sys/dev/random/randomdev.c#18 integrate
.. //depot/projects/smpng/sys/ia64/ia64/machdep.c#74 integrate
.. //depot/projects/smpng/sys/kern/kern_intr.c#36 integrate
.. //depot/projects/smpng/sys/kern/subr_witness.c#109 integrate
.. //depot/projects/smpng/sys/net/if_faith.c#17 integrate
.. //depot/projects/smpng/sys/net/if_loop.c#25 integrate
.. //depot/projects/smpng/sys/net/route.c#15 integrate
.. //depot/projects/smpng/sys/net/route.h#15 integrate
.. //depot/projects/smpng/sys/net/rtsock.c#30 integrate
.. //depot/projects/smpng/sys/netinet/in_pcb.c#39 integrate
.. //depot/projects/smpng/sys/netinet/in_pcb.h#25 integrate
.. //depot/projects/smpng/sys/netinet/in_rmx.c#9 integrate
.. //depot/projects/smpng/sys/netinet/ip_divert.c#28 integrate
.. //depot/projects/smpng/sys/netinet/ip_fastfwd.c#2 integrate
.. //depot/projects/smpng/sys/netinet/ip_fw2.c#24 integrate
.. //depot/projects/smpng/sys/netinet/ip_icmp.c#22 integrate
.. //depot/projects/smpng/sys/netinet/ip_input.c#45 integrate
.. //depot/projects/smpng/sys/netinet/ip_output.c#47 integrate
.. //depot/projects/smpng/sys/netinet/raw_ip.c#32 integrate
.. //depot/projects/smpng/sys/netinet/tcp_hostcache.c#1 branch
.. //depot/projects/smpng/sys/netinet/tcp_input.c#42 integrate
.. //depot/projects/smpng/sys/netinet/tcp_output.c#18 integrate
.. //depot/projects/smpng/sys/netinet/tcp_subr.c#38 integrate
.. //depot/projects/smpng/sys/netinet/tcp_syncache.c#24 integrate
.. //depot/projects/smpng/sys/netinet/tcp_timer.c#15 integrate
.. //depot/projects/smpng/sys/netinet/tcp_usrreq.c#22 integrate
.. //depot/projects/smpng/sys/netinet/tcp_var.h#17 integrate
.. //depot/projects/smpng/sys/netinet/udp_usrreq.c#34 integrate
.. //depot/projects/smpng/sys/netinet6/icmp6.c#20 integrate
.. //depot/projects/smpng/sys/netinet6/in6_pcb.c#25 integrate
.. //depot/projects/smpng/sys/netinet6/in6_rmx.c#6 integrate
.. //depot/projects/smpng/sys/netinet6/in6_src.c#15 integrate
.. //depot/projects/smpng/sys/netinet6/ip6_forward.c#9 integrate
.. //depot/projects/smpng/sys/netinet6/ip6_input.c#28 integrate
.. //depot/projects/smpng/sys/netinet6/ip6_output.c#24 integrate
.. //depot/projects/smpng/sys/netinet6/udp6_output.c#14 integrate
.. //depot/projects/smpng/sys/opencrypto/cryptodev.c#10 integrate
.. //depot/projects/smpng/sys/rpc/rpcv2.h#2 delete
.. //depot/projects/smpng/sys/vm/vm_map.c#50 integrate

Differences ...

==== //depot/projects/smpng/sys/amd64/conf/GENERIC#10 (text+ko) ====

@@ -16,7 +16,7 @@
 # If you are in doubt as to the purpose or necessity of a line, check first 
 # in NOTES.
 #
-# $FreeBSD: src/sys/amd64/conf/GENERIC,v 1.397 2003/11/08 03:17:36 peter Exp $
+# $FreeBSD: src/sys/amd64/conf/GENERIC,v 1.398 2003/11/19 18:11:27 peter Exp $
 
 machine		amd64
 cpu		HAMMER
@@ -25,7 +25,7 @@
 #To statically compile in device wiring instead of /boot/device.hints
 #hints		"GENERIC.hints"		#Default places to look for devices.
 
-#makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
+makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
 makeoptions	NO_MODULES=not_yet
 
 options 	SCHED_4BSD		#4BSD scheduler
@@ -64,6 +64,11 @@
 options 	WITNESS			#Enable checks to detect deadlocks and cycles
 options 	WITNESS_SKIPSPIN	#Don't run witness on spinlocks for speed
 
+# Make an SMP-capable kernel by default
+options 	SMP			# Symmetric MultiProcessor Kernel
+# Workarounds for some known-to-be-broken chipsets (nVidia nForce3-Pro150)
+device		atpic			# 8259A compatability
+
 device		acpi
 device		isa
 device		pci
@@ -92,8 +97,7 @@
 device		isp		# Qlogic family
 device		mpt		# LSI-Logic MPT-Fusion
 #device		ncr		# NCR/Symbios Logic
-#XXX #error unknown architecture
-#device		sym		# NCR/Symbios Logic (newer chipsets + those of `ncr')
+device		sym		# NCR/Symbios Logic (newer chipsets + those of `ncr')
 device		trm		# Tekram DC395U/UW/F DC315U adapters
 
 device		adv		# Advansys SCSI adapters

==== //depot/projects/smpng/sys/boot/i386/boot0/boot0.s#3 (text+ko) ====

@@ -13,7 +13,7 @@
 # purpose.
 #
 
-# $FreeBSD: src/sys/boot/i386/boot0/boot0.s,v 1.26 2003/06/01 20:41:04 obrien Exp $
+# $FreeBSD: src/sys/boot/i386/boot0/boot0.s,v 1.27 2003/11/20 20:28:18 jhb Exp $
 
 # A 512-byte boot manager.
 
@@ -25,7 +25,7 @@
 		.set PRT_OFF,0x1be		# Partition table
 
 		.set TBL0SZ,0x3 		# Table 0 size
-		.set TBL1SZ,0xc 		# Table 1 size
+		.set TBL1SZ,0xb 		# Table 1 size
 
 		.set MAGIC,0xaa55		# Magic: bootable
 		.set B0MAGIC,0xbb66		# Identification

==== //depot/projects/smpng/sys/conf/files#96 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files,v 1.853 2003/11/15 19:26:05 njl Exp $
+# $FreeBSD: src/sys/conf/files,v 1.854 2003/11/20 20:07:37 andre Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1457,6 +1457,7 @@
 netinet/ip_output.c	optional inet
 netinet/raw_ip.c	optional inet
 netinet/tcp_debug.c	optional tcpdebug
+netinet/tcp_hostcache.c	optional inet
 netinet/tcp_input.c	optional inet
 netinet/tcp_output.c	optional inet
 netinet/tcp_subr.c	optional inet

==== //depot/projects/smpng/sys/dev/acpica/acpi.c#52 (text+ko) ====

@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/acpica/acpi.c,v 1.107 2003/11/15 19:18:29 njl Exp $
+ *	$FreeBSD: src/sys/dev/acpica/acpi.c,v 1.108 2003/11/19 20:27:06 njl Exp $
  */
 
 #include "opt_acpi.h"
@@ -125,6 +125,7 @@
     DEVMETHOD(device_identify,		acpi_identify),
     DEVMETHOD(device_probe,		acpi_probe),
     DEVMETHOD(device_attach,		acpi_attach),
+    DEVMETHOD(device_detach,		bus_generic_detach),
     DEVMETHOD(device_shutdown,		bus_generic_shutdown),
     DEVMETHOD(device_suspend,		bus_generic_suspend),
     DEVMETHOD(device_resume,		bus_generic_resume),

==== //depot/projects/smpng/sys/dev/acpica/acpi_cpu.c#16 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003 Nate Lawson
+ * Copyright (c) 2003 Nate Lawson (SDG)
  * Copyright (c) 2001 Michael Smith
  * All rights reserved.
  *
@@ -26,24 +26,25 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_cpu.c,v 1.19 2003/11/15 19:26:05 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_cpu.c,v 1.20 2003/11/19 20:27:06 njl Exp $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
+#include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/pcpu.h>
+#include <sys/power.h>
 #include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/power.h>
 #include <sys/sbuf.h>
-#include <sys/pcpu.h>
 #include <sys/smp.h>
 
 #include <dev/pci/pcivar.h>
+#include <machine/atomic.h>
 #include <machine/bus.h>
-#include <sys/rman.h>
 #ifdef __ia64__
 #include <machine/pal.h>
 #endif
+#include <sys/rman.h>
 
 #include "acpi.h"
 #include <dev/acpica/acpivar.h>
@@ -77,9 +78,11 @@
     device_t		 cpu_dev;
     ACPI_HANDLE		 cpu_handle;
     uint32_t		 cpu_id;	/* ACPI processor id */
+    uint32_t		 cpu_p_blk;	/* ACPI P_BLK location */
+    uint32_t		 cpu_p_blk_len;	/* P_BLK length (must be 6). */
     struct resource	*cpu_p_cnt;	/* Throttling control register */
     struct acpi_cx	 cpu_cx_states[MAX_CX_STATES];
-    int			 cpu_bm_ok;	/* Bus mastering control available. */
+    int			 cpu_cx_count;	/* Number of valid Cx states. */
 };
 
 #define CPU_GET_REG(reg, width) 					\
@@ -116,10 +119,9 @@
 #define PCI_REVISION_4M		3
 
 /* Platform hardware resource information. */
-static uint32_t		 cpu_p_blk;	/* ACPI P_BLK location */
-static uint32_t		 cpu_p_blk_len;	/* P_BLK length (must be 6). */
 static uint32_t		 cpu_smi_cmd;	/* Value to write to SMI_CMD. */
 static uint8_t		 cpu_pstate_cnt;/* Register to take over throttling. */
+static uint8_t		 cpu_cst_cnt;	/* Indicate we are _CST aware. */
 static uint32_t		 cpu_rid;	/* Driver-wide resource id. */
 static uint32_t		 cpu_quirks;	/* Indicate any hardware bugs. */
 
@@ -128,6 +130,9 @@
 static uint32_t		 cpu_cx_next;	/* State to use for next sleep. */
 static uint32_t		 cpu_non_c3;	/* Index of lowest non-C3 state. */
 static struct acpi_cx_stats cpu_cx_stats[MAX_CX_STATES];
+#ifdef SMP
+static int		 cpu_idle_busy;	/* Count of CPUs in acpi_cpu_idle. */
+#endif
 
 /* Values for sysctl. */
 static uint32_t		 cpu_current_state;
@@ -146,11 +151,13 @@
 
 static int	acpi_cpu_probe(device_t dev);
 static int	acpi_cpu_attach(device_t dev);
+static int	acpi_cpu_shutdown(device_t dev);
 static int	acpi_cpu_throttle_probe(struct acpi_cpu_softc *sc);
 static int	acpi_cpu_cx_probe(struct acpi_cpu_softc *sc);
 static int	acpi_cpu_cx_cst(struct acpi_cpu_softc *sc);
 static void	acpi_cpu_startup(void *arg);
 static void	acpi_cpu_startup_throttling(void);
+static void	acpi_cpu_startup_cx(void);
 static void	acpi_cpu_throttle_set(uint32_t speed);
 static void	acpi_cpu_idle(void);
 static void	acpi_cpu_c1(void);
@@ -166,6 +173,7 @@
     /* Device interface */
     DEVMETHOD(device_probe,	acpi_cpu_probe),
     DEVMETHOD(device_attach,	acpi_cpu_attach),
+    DEVMETHOD(device_shutdown,	acpi_cpu_shutdown),
 
     {0, 0}
 };
@@ -178,6 +186,7 @@
 
 static devclass_t acpi_cpu_devclass;
 DRIVER_MODULE(acpi_cpu, acpi, acpi_cpu_driver, acpi_cpu_devclass, 0, 0);
+
 static int
 acpi_cpu_probe(device_t dev)
 {
@@ -231,8 +240,9 @@
      */
     cpu_id = pobj.Processor.ProcId;
     if (cpu_id > MAXCPU - 1) {
-	device_printf(dev, "CPU id %d too large\n", cpu_id);
-	return (ENXIO);
+	device_printf(dev, "CPU id %d too large (%d max)\n", cpu_id,
+		      MAXCPU - 1);
+	return_VALUE (ENXIO);
     }
     if (mp_ncpus > 1) {
 	struct pcpu	*pcpu_data;
@@ -248,7 +258,7 @@
 	}
 	if (i == MAXCPU) {
 	    device_printf(dev, "Couldn't find CPU for id %d\n", cpu_id);
-	    return (ENXIO);
+	    return_VALUE (ENXIO);
 	}
     } else
 #endif /* SMP */
@@ -272,11 +282,10 @@
     AcpiEvaluateObject(sc->cpu_handle, "_INI", NULL, NULL);
 
     /* Get various global values from the Processor object. */
-    cpu_p_blk = pobj.Processor.PblkAddress;
-    cpu_p_blk_len = pobj.Processor.PblkLength;
-    ACPI_DEBUG_PRINT((ACPI_DB_IO, "acpi_cpu%d: P_BLK at %#x/%d%s\n",
-		     device_get_unit(dev), cpu_p_blk, cpu_p_blk_len,
-		     sc->cpu_p_cnt ? "" : " (shadowed)"));
+    sc->cpu_p_blk = pobj.Processor.PblkAddress;
+    sc->cpu_p_blk_len = pobj.Processor.PblkLength;
+    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_BLK at %#x/%d\n",
+		     device_get_unit(dev), sc->cpu_p_blk, sc->cpu_p_blk_len));
 
     acpi_sc = acpi_device_get_parent_softc(dev);
     sysctl_ctx_init(&acpi_cpu_sysctl_ctx);
@@ -297,7 +306,8 @@
     if (thr_ret == 0 || cx_ret == 0) {
 	status = AcpiInstallNotifyHandler(sc->cpu_handle, ACPI_DEVICE_NOTIFY,
 					  acpi_cpu_notify, sc);
-	AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cpu_startup, sc);
+	if (device_get_unit(dev) == 0)
+	    AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cpu_startup, NULL);
     } else {
 	sysctl_ctx_free(&acpi_cpu_sysctl_ctx);
     }
@@ -306,6 +316,24 @@
 }
 
 static int
+acpi_cpu_shutdown(device_t dev)
+{
+    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+    /* Disable any entry to the idle function. */
+    cpu_cx_count = 0;
+
+#ifdef SMP
+    /* Wait for all processors to exit acpi_cpu_idle(). */
+    smp_rendezvous(NULL, NULL, NULL, NULL);
+    while (cpu_idle_busy > 0)
+	DELAY(1);
+#endif
+
+    return_VALUE (0);
+}
+
+static int
 acpi_cpu_throttle_probe(struct acpi_cpu_softc *sc)
 {
     uint32_t		 duty_end;
@@ -319,10 +347,13 @@
     ACPI_ASSERTLOCK;
 
     /* Get throttling parameters from the FADT.  0 means not supported. */
-    cpu_smi_cmd = AcpiGbl_FADT->SmiCmd;
-    cpu_pstate_cnt = AcpiGbl_FADT->PstateCnt;
-    cpu_duty_offset = AcpiGbl_FADT->DutyOffset;
-    cpu_duty_width = AcpiGbl_FADT->DutyWidth;
+    if (device_get_unit(sc->cpu_dev) == 0) {
+	cpu_smi_cmd = AcpiGbl_FADT->SmiCmd;
+	cpu_pstate_cnt = AcpiGbl_FADT->PstateCnt;
+	cpu_cst_cnt = AcpiGbl_FADT->CstCnt;
+	cpu_duty_offset = AcpiGbl_FADT->DutyOffset;
+	cpu_duty_width = AcpiGbl_FADT->DutyWidth;
+    }
     if (cpu_duty_width == 0 || (cpu_quirks & CPU_QUIRK_NO_THROTTLE) != 0)
 	return (ENXIO);
 
@@ -355,7 +386,7 @@
 	memcpy(&gas, obj.Buffer.Pointer + 3, sizeof(gas));
 	sc->cpu_p_cnt = acpi_bus_alloc_gas(sc->cpu_dev, &cpu_rid, &gas);
 	if (sc->cpu_p_cnt != NULL) {
-	    ACPI_DEBUG_PRINT((ACPI_DB_IO, "acpi_cpu%d: P_CNT from _PTC\n",
+	    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_CNT from _PTC\n",
 			     device_get_unit(sc->cpu_dev)));
 	}
     }
@@ -363,14 +394,14 @@
     /* If _PTC not present or other failure, try the P_BLK. */
     if (sc->cpu_p_cnt == NULL) {
 	/* The spec says P_BLK must be at least 6 bytes long. */
-	if (cpu_p_blk_len != 6)
+	if (sc->cpu_p_blk_len != 6)
 	    return (ENXIO);
-	gas.Address = cpu_p_blk;
+	gas.Address = sc->cpu_p_blk;
 	gas.AddressSpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
 	gas.RegisterBitWidth = 32;
 	sc->cpu_p_cnt = acpi_bus_alloc_gas(sc->cpu_dev, &cpu_rid, &gas);
 	if (sc->cpu_p_cnt != NULL) {
-	    ACPI_DEBUG_PRINT((ACPI_DB_IO, "acpi_cpu%d: P_CNT from P_BLK\n",
+	    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_CNT from P_BLK\n",
 			     device_get_unit(sc->cpu_dev)));
 	} else {
 	    device_printf(sc->cpu_dev, "Failed to attach throttling P_CNT\n");
@@ -379,25 +410,6 @@
     }
     cpu_rid++;
 
-    SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
-		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		   OID_AUTO, "max_speed", CTLFLAG_RD,
-		   &cpu_max_state, 0, "maximum CPU speed");
-    SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
-		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		   OID_AUTO, "current_speed", CTLFLAG_RD,
-		   &cpu_current_state, 0, "current CPU speed");
-    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
-		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "performance_speed",
-		    CTLTYPE_INT | CTLFLAG_RW, &cpu_performance_state,
-		    0, acpi_cpu_throttle_sysctl, "I", "");
-    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
-		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "economy_speed",
-		    CTLTYPE_INT | CTLFLAG_RW, &cpu_economy_state,
-		    0, acpi_cpu_throttle_sysctl, "I", "");
-
     return (0);
 }
 
@@ -406,25 +418,25 @@
 {
     ACPI_GENERIC_ADDRESS gas;
     struct acpi_cx	*cx_ptr;
-    struct sbuf		 sb;
-    int			 i, error;
+    int			 error;
+
+    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
     /* Bus mastering arbitration control is needed for C3. */
     if (AcpiGbl_FADT->V1_Pm2CntBlk == 0 || AcpiGbl_FADT->Pm2CntLen == 0) {
 	cpu_quirks |= CPU_QUIRK_NO_C3;
-	if (bootverbose)
-	    device_printf(sc->cpu_dev, "No BM control, C3 disabled.\n");
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			 "acpi_cpu%d: No BM control, C3 disabled\n",
+			 device_get_unit(sc->cpu_dev)));
     }
 
     /*
      * First, check for the ACPI 2.0 _CST sleep states object.
      * If not usable, fall back to the P_BLK's P_LVL2 and P_LVL3.
      */
-    cpu_cx_count = 0;
+    sc->cpu_cx_count = 0;
     error = acpi_cpu_cx_cst(sc);
     if (error != 0) {
-	if (cpu_p_blk_len != 6)
-	    return (ENXIO);
 	cx_ptr = sc->cpu_cx_states;
 
 	/* C1 has been required since just after ACPI 1.0 */
@@ -432,13 +444,16 @@
 	cx_ptr->trans_lat = 0;
 	cpu_non_c3 = 0;
 	cx_ptr++;
-	cpu_cx_count++;
+	sc->cpu_cx_count++;
+
+	if (sc->cpu_p_blk_len != 6)
+	    goto done;
 
 	/* Validate and allocate resources for C2 (P_LVL2). */
 	gas.AddressSpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
 	gas.RegisterBitWidth = 8;
 	if (AcpiGbl_FADT->Plvl2Lat < 100) {
-	    gas.Address = cpu_p_blk + 4;
+	    gas.Address = sc->cpu_p_blk + 4;
 	    cx_ptr->p_lvlx = acpi_bus_alloc_gas(sc->cpu_dev, &cpu_rid, &gas);
 	    if (cx_ptr->p_lvlx != NULL) {
 		cpu_rid++;
@@ -446,7 +461,7 @@
 		cx_ptr->trans_lat = AcpiGbl_FADT->Plvl2Lat;
 		cpu_non_c3 = 1;
 		cx_ptr++;
-		cpu_cx_count++;
+		sc->cpu_cx_count++;
 	    }
 	}
 
@@ -454,47 +469,23 @@
 	if (AcpiGbl_FADT->Plvl3Lat < 1000 &&
 	    (cpu_quirks & CPU_QUIRK_NO_C3) == 0) {
 
-	    gas.Address = cpu_p_blk + 5;
+	    gas.Address = sc->cpu_p_blk + 5;
 	    cx_ptr->p_lvlx = acpi_bus_alloc_gas(sc->cpu_dev, &cpu_rid, &gas);
 	    if (cx_ptr->p_lvlx != NULL) {
 		cpu_rid++;
 		cx_ptr->type = ACPI_STATE_C3;
 		cx_ptr->trans_lat = AcpiGbl_FADT->Plvl3Lat;
 		cx_ptr++;
-		cpu_cx_count++;
+		sc->cpu_cx_count++;
 	    }
 	}
     }
 
+done:
     /* If no valid registers were found, don't attach. */
-    if (cpu_cx_count == 0)
+    if (sc->cpu_cx_count == 0)
 	return (ENXIO);
 
-    sbuf_new(&sb, cpu_cx_supported, sizeof(cpu_cx_supported), SBUF_FIXEDLEN);
-    for (i = 0; i < cpu_cx_count; i++) {
-	sbuf_printf(&sb, "C%d/%d ", sc->cpu_cx_states[i].type,
-		    sc->cpu_cx_states[i].trans_lat);
-    }
-    sbuf_trim(&sb);
-    sbuf_finish(&sb);
-    SYSCTL_ADD_STRING(&acpi_cpu_sysctl_ctx,
-		      SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		      OID_AUTO, "cx_supported", CTLFLAG_RD, cpu_cx_supported,
-		      0, "Cx/microsecond values for supported Cx states");
-    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
-		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "cx_lowest", CTLTYPE_INT | CTLFLAG_RW,
-		    NULL, 0, acpi_cpu_cx_lowest_sysctl, "I",
-		    "lowest Cx sleep state to use");
-    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
-		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "cx_history", CTLTYPE_STRING | CTLFLAG_RD,
-		    NULL, 0, acpi_cpu_history_sysctl, "A", "");
-
-    /* Set next sleep state and hook the idle function. */
-    cpu_cx_next = cpu_cx_lowest;
-    cpu_idle_hook = acpi_cpu_idle;
-
     return (0);
 }
 
@@ -514,6 +505,8 @@
     uint32_t	 count;
     int		 i;
 
+    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
     buf.Pointer = NULL;
     buf.Length = ACPI_ALLOCATE_BUFFER;
     status = AcpiEvaluateObject(sc->cpu_handle, "_CST", NULL, &buf);
@@ -534,13 +527,12 @@
 	count = top->Package.Count - 1;
     }
     if (count > MAX_CX_STATES) {
-	device_printf(sc->cpu_dev, "_CST has too many states (%d)\n",
-		      count);
+	device_printf(sc->cpu_dev, "_CST has too many states (%d)\n", count);
 	count = MAX_CX_STATES;
     }
 
     /* Set up all valid states. */
-    cpu_cx_count = 0;
+    sc->cpu_cx_count = 0;
     cx_ptr = sc->cpu_cx_states;
     for (i = 0; i < count; i++) {
 	pkg = &top->Package.Elements[i + 1];
@@ -559,11 +551,13 @@
 	case ACPI_STATE_C1:
 	    cpu_non_c3 = i;
 	    cx_ptr++;
-	    cpu_cx_count++;
+	    sc->cpu_cx_count++;
 	    continue;
 	case ACPI_STATE_C2:
 	    if (cx_ptr->trans_lat > 100) {
-		device_printf(sc->cpu_dev, "C2[%d] not available.\n", i);
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				 "acpi_cpu%d: C2[%d] not available.\n",
+				 device_get_unit(sc->cpu_dev), i));
 		continue;
 	    }
 	    cpu_non_c3 = i;
@@ -573,7 +567,9 @@
 	    if (cx_ptr->trans_lat > 1000 ||
 		(cpu_quirks & CPU_QUIRK_NO_C3) != 0) {
 
-		device_printf(sc->cpu_dev, "C3[%d] not available.\n", i);
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				 "acpi_cpu%d: C3[%d] not available.\n",
+				 device_get_unit(sc->cpu_dev), i));
 		continue;
 	    }
 	    break;
@@ -591,10 +587,12 @@
 	acpi_PkgGas(sc->cpu_dev, pkg, 0, &cpu_rid, &cx_ptr->p_lvlx);
 	if (cx_ptr->p_lvlx != NULL) {
 	    cpu_rid++;
-	    device_printf(sc->cpu_dev, "C%d state %d lat\n", cx_ptr->type,
-			  cx_ptr->trans_lat);
+	    ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			     "acpi_cpu%d: Got C%d - %d latency\n",
+			     device_get_unit(sc->cpu_dev), cx_ptr->type,
+			     cx_ptr->trans_lat));
 	    cx_ptr++;
-	    cpu_cx_count++;
+	    sc->cpu_cx_count++;
 	}
     }
     AcpiOsFree(buf.Pointer);
@@ -604,18 +602,13 @@
 
 /*
  * Call this *after* all CPUs have been attached.
- *
- * Takes the ACPI lock to avoid fighting anyone over the SMI command
- * port.  Could probably lock less code.
  */
 static void
 acpi_cpu_startup(void *arg)
 {
-    struct acpi_cpu_softc *sc = (struct acpi_cpu_softc *)arg;
-    ACPI_LOCK_DECL;
+    struct acpi_cpu_softc *sc;
+    int count, i;
 
-    ACPI_LOCK;
-
     /* Get set of CPU devices */
     devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices);
 
@@ -623,16 +616,35 @@
     EVENTHANDLER_REGISTER(power_profile_change, acpi_cpu_power_profile,
 			  NULL, 0);
 
+    /*
+     * Make sure all the processors' Cx counts match.  We should probably
+     * also check the contents of each.  However, no known systems have
+     * non-matching Cx counts so we'll deal with this later.
+     */
+    count = MAX_CX_STATES;
+    for (i = 0; i < cpu_ndevices; i++) {
+	sc = device_get_softc(cpu_devices[i]);
+	count = min(sc->cpu_cx_count, count);
+    }
+    cpu_cx_count = count;
+
+    /* Perform throttling and Cx final initialization. */
+    sc = device_get_softc(cpu_devices[0]);
     if (sc->cpu_p_cnt != NULL)
 	acpi_cpu_startup_throttling();
-    else
-	ACPI_UNLOCK;
+    if (cpu_cx_count > 0)
+	acpi_cpu_startup_cx();
 }
 
+/*
+ * Takes the ACPI lock to avoid fighting anyone over the SMI command
+ * port.
+ */
 static void
 acpi_cpu_startup_throttling()
 {
     int cpu_temp_speed;
+    ACPI_LOCK_DECL;
 
     /* Initialise throttling states */
     cpu_max_state = CPU_MAX_SPEED;
@@ -653,12 +665,32 @@
 	cpu_economy_state = cpu_temp_speed;
     }
 
+    SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
+		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		   OID_AUTO, "max_speed", CTLFLAG_RD,
+		   &cpu_max_state, 0, "maximum CPU speed");
+    SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
+		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		   OID_AUTO, "current_speed", CTLFLAG_RD,
+		   &cpu_current_state, 0, "current CPU speed");
+    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
+		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		    OID_AUTO, "performance_speed",
+		    CTLTYPE_INT | CTLFLAG_RW, &cpu_performance_state,
+		    0, acpi_cpu_throttle_sysctl, "I", "");
+    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
+		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		    OID_AUTO, "economy_speed",
+		    CTLTYPE_INT | CTLFLAG_RW, &cpu_economy_state,
+		    0, acpi_cpu_throttle_sysctl, "I", "");
+
     /* If ACPI 2.0+, signal platform that we are taking over throttling. */
-    if (cpu_pstate_cnt != 0)
+    if (cpu_pstate_cnt != 0) {
+	ACPI_LOCK;
 	AcpiOsWritePort(cpu_smi_cmd, cpu_pstate_cnt, 8);
+	ACPI_UNLOCK;
+    }
 
-    ACPI_UNLOCK;
-
     /* Set initial speed */
     acpi_cpu_power_profile(NULL);
 
@@ -667,6 +699,50 @@
 	   CPU_SPEED_PRINTABLE(cpu_current_state));
 }
 
+static void
+acpi_cpu_startup_cx()
+{
+    struct acpi_cpu_softc *sc;
+    struct sbuf		 sb;
+    int i;
+    ACPI_LOCK_DECL;
+
+    sc = device_get_softc(cpu_devices[0]);
+    sbuf_new(&sb, cpu_cx_supported, sizeof(cpu_cx_supported), SBUF_FIXEDLEN);
+    for (i = 0; i < cpu_cx_count; i++) {
+	sbuf_printf(&sb, "C%d/%d ", sc->cpu_cx_states[i].type,
+		    sc->cpu_cx_states[i].trans_lat);
+    }
+    sbuf_trim(&sb);
+    sbuf_finish(&sb);
+    SYSCTL_ADD_STRING(&acpi_cpu_sysctl_ctx,
+		      SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		      OID_AUTO, "cx_supported", CTLFLAG_RD, cpu_cx_supported,
+		      0, "Cx/microsecond values for supported Cx states");
+    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
+		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		    OID_AUTO, "cx_lowest", CTLTYPE_INT | CTLFLAG_RW,
+		    NULL, 0, acpi_cpu_cx_lowest_sysctl, "I",
+		    "lowest Cx sleep state to use");
+    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
+		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
+		    OID_AUTO, "cx_history", CTLTYPE_STRING | CTLFLAG_RD,
+		    NULL, 0, acpi_cpu_history_sysctl, "A", "");
+
+#ifdef notyet
+    /* Signal platform that we can handle _CST notification. */
+    if (cpu_cst_cnt != 0) {
+	ACPI_LOCK;
+	AcpiOsWritePort(cpu_smi_cmd, cpu_cst_cnt, 8);
+	ACPI_UNLOCK;
+    }
+#endif
+
+    /* Take over idling from cpu_idle_default(). */
+    cpu_cx_next = cpu_cx_lowest;
+    cpu_idle_hook = acpi_cpu_idle;
+}
+
 /*
  * Set CPUs to the new state.
  *
@@ -717,21 +793,30 @@
 static void
 acpi_cpu_idle()
 {
-    int bm_active, i, asleep;
-    struct acpi_cx *cx_next;
-    struct acpi_cpu_softc	*sc;
-    uint32_t start_time, end_time;
+    struct	acpi_cpu_softc *sc;
+    struct	acpi_cx *cx_next;
+    uint32_t	start_time, end_time;
+    int		bm_active, i, asleep;
 
+#ifdef SMP
     /* Look up our CPU id and to get our softc. */
     sc = cpu_softc[PCPU_GET(acpi_id)];
+#else
+    sc = cpu_softc[0];
+#endif
     KASSERT(sc != NULL, ("NULL softc for %d", PCPU_GET(acpi_id)));
 
     /* If disabled, return immediately. */
-    if (cpu_cx_lowest < 0 || cpu_cx_count == 0) {
+    if (cpu_cx_count == 0) {
 	ACPI_ENABLE_IRQS();
 	return;
     }
 
+#ifdef SMP
+    /* Record that a CPU is in the idle function. */
+    atomic_add_int(&cpu_idle_busy, 1);
+#endif
+
     /*
      * Check for bus master activity.  If there was activity, clear
      * the bit and use the lowest non-C3 state.  Note that the USB
@@ -749,6 +834,9 @@
     /* Perform the actual sleep based on the Cx-specific semantics. */
     cx_next = &sc->cpu_cx_states[cpu_cx_next];
     switch (cx_next->type) {
+    case ACPI_STATE_C0:
+	panic("acpi_cpu_idle: attempting to sleep in C0");
+	/* NOTREACHED */
     case ACPI_STATE_C1:
 	/* Execute HLT (or equivalent) and wait for an interrupt. */
 	acpi_cpu_c1();
@@ -826,6 +914,11 @@
 	    }
 	}
     }
+
+#ifdef SMP
+    /* Decrement reference count checked by acpi_cpu_shutdown(). */
+    atomic_subtract_int(&cpu_idle_busy, 1);
+#endif
 }
 
 /* Put the CPU in C1 in a machine-dependant way. */
@@ -854,6 +947,7 @@
 /*
  * Re-evaluate the _PSS and _CST objects when we are notified that they
  * have changed.
+ *
  * XXX Re-evaluation disabled until locking is done.
  */
 static void
@@ -1027,7 +1121,7 @@
     error = sysctl_handle_int(oidp, &val, 0, req);
     if (error != 0 || req->newptr == NULL)
 	return (error);
-    if (val < -1 || val > cpu_cx_count - 1)
+    if (val < 0 || val > cpu_cx_count - 1)
 	return (EINVAL);
 
     /* Use the new value for the next idle slice. */

==== //depot/projects/smpng/sys/dev/acpica/acpi_pci_link.c#10 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_pci_link.c,v 1.9 2003/11/14 21:36:09 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_pci_link.c,v 1.10 2003/11/20 21:23:49 jhb Exp $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -924,7 +924,7 @@
 		}
 
 		/* try with lower penalty IRQ. */
-		for (i = 0; i < link->number_of_interrupts - 1; i++) {
+		for (i = 0; i < link->number_of_interrupts; i++) {
 			irq1 = link->sorted_irq[i];
 			error = acpi_pci_link_set_irq(link, irq1);
 			if (error == AE_OK) {

==== //depot/projects/smpng/sys/dev/random/randomdev.c#18 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/random/randomdev.c,v 1.45 2003/11/17 23:02:21 markm Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/random/randomdev.c,v 1.46 2003/11/20 15:35:48 markm Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,12 +78,19 @@
 
 MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers");
 
-/* FIFO queues holding harvested entropy */
-static struct harvestfifo {
+/* Lockable FIFO queue holding entropy buffers */
+struct entropyfifo {
 	struct mtx lock;
 	int count;
 	STAILQ_HEAD(harvestlist, harvest) head;
-} harvestfifo[ENTROPYSOURCE];
+};
+
+/* Empty entropy buffers */
+static struct entropyfifo emptyfifo;
+#define EMPTYBUFFERS	1024
+
+/* Harvested entropy */
+static struct entropyfifo harvestfifo[ENTROPYSOURCE];
 
 static struct random_systat {
 	u_int		seeded;	/* 0 causes blocking 1 allows normal output */
@@ -239,10 +246,20 @@
 		random_systat.seeded = 1;
 
 		/* Initialise the harvest fifos */
+		STAILQ_INIT(&emptyfifo.head);
+		emptyfifo.count = 0;
+		mtx_init(&emptyfifo.lock, "entropy harvest buffers", NULL,
+			MTX_SPIN);
+		for (i = 0; i < EMPTYBUFFERS; i++) {
+			np = malloc(sizeof(struct harvest), M_ENTROPY,
+				M_WAITOK);
+			STAILQ_INSERT_TAIL(&emptyfifo.head, np, next);
+		}
 		for (i = 0; i < ENTROPYSOURCE; i++) {
 			STAILQ_INIT(&harvestfifo[i].head);
 			harvestfifo[i].count = 0;
-			mtx_init(&harvestfifo[i].lock, "entropy harvest", NULL, MTX_DEF);
+			mtx_init(&harvestfifo[i].lock, "entropy harvest", NULL,
+				MTX_SPIN);
 		}
 
 		if (bootverbose)
@@ -274,6 +291,12 @@
 		tsleep((void *)&random_kthread_control, PUSER, "term", 0);
 
 		/* Destroy the harvest fifos */
+		while (!STAILQ_EMPTY(&emptyfifo.head)) {
+			np = STAILQ_FIRST(&emptyfifo.head);
+			STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
+			free(np, M_ENTROPY);
+		}
+		mtx_destroy(&emptyfifo.lock);
 		for (i = 0; i < ENTROPYSOURCE; i++) {
 			while (!STAILQ_EMPTY(&harvestfifo[i].head)) {
 				np = STAILQ_FIRST(&harvestfifo[i].head);
@@ -318,7 +341,7 @@
 			found = 0;
 
 			/* Lock up queue draining */
-			mtx_lock(&harvestfifo[source].lock);
+			mtx_lock_spin(&harvestfifo[source].lock);
 
 			if (!STAILQ_EMPTY(&harvestfifo[source].head)) {
 
@@ -327,17 +350,26 @@
 				event = STAILQ_FIRST(&harvestfifo[source].head);
 				STAILQ_REMOVE_HEAD(&harvestfifo[source].head,
 					next);
+
 				active = found = 1;
 
 			}
 
 			/* Unlock the queue */
-			mtx_unlock(&harvestfifo[source].lock);
+			mtx_unlock_spin(&harvestfifo[source].lock);
 
 			/* Deal with the event and dispose of it */
 			if (found) {
+
 				random_process_event(event);
-				free(event, M_ENTROPY);
+
+				/* Lock the empty event buffer fifo */
+				mtx_lock_spin(&emptyfifo.lock);
+
+				STAILQ_INSERT_TAIL(&emptyfifo.head, event, next);
+
+				mtx_unlock_spin(&emptyfifo.lock);
+
 			}
 
 		}
@@ -362,14 +394,26 @@
 	struct harvest	*event;
 
 	/* Lock the particular fifo */
-	mtx_lock(&harvestfifo[origin].lock);
+	mtx_lock_spin(&harvestfifo[origin].lock);
 
-	/* Don't make the harvest queues too big - memory is precious */
+	/* Don't make the harvest queues too big - help to prevent
+	 * low-grade entropy swamping
+	 */
 	if (harvestfifo[origin].count < RANDOM_FIFO_MAX) {
 		
-		event = malloc(sizeof(struct harvest), M_ENTROPY, M_NOWAIT);
+		/* Lock the empty event buffer fifo */
+		mtx_lock_spin(&emptyfifo.lock);
+
+		if (!STAILQ_EMPTY(&emptyfifo.head)) {
+			event = STAILQ_FIRST(&emptyfifo.head);
+			STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
+		}
+		else
+			event = NULL;
+
+		mtx_unlock_spin(&emptyfifo.lock);
 
-		/* If we can't malloc() a buffer, tough */
+		/* If we didn't obtain a buffer, tough */
 		if (event) {
 
 			/* Add the harvested data to the fifo */
@@ -389,7 +433,7 @@
 
 	}
 
-	mtx_unlock(&harvestfifo[origin].lock);
+	mtx_unlock_spin(&harvestfifo[origin].lock);
 
 }
 

==== //depot/projects/smpng/sys/ia64/ia64/machdep.c#74 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/ia64/ia64/machdep.c,v 1.171 2003/11/15 18:58:29 njl Exp $
+ * $FreeBSD: src/sys/ia64/ia64/machdep.c,v 1.172 2003/11/20 16:42:39 marcel Exp $
  */
 
 #include "opt_compat.h"
@@ -361,7 +361,7 @@
 	KASSERT(size >= pcpusz + sizeof(struct pcb),
 	    ("%s: too small an allocation for pcpu", __func__));
 	pcpu->pc_pcb = (struct pcb *)((char*)pcpu + pcpusz);
-	pcpu->pc_acpi_id = 0xffffffff;
+	pcpu->pc_acpi_id = cpuid;
 }
 
 void

==== //depot/projects/smpng/sys/kern/kern_intr.c#36 (text+ko) ====

@@ -25,7 +25,7 @@
  */

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list