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