From owner-p4-projects@FreeBSD.ORG Thu Nov 20 13:29:44 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6ECBE16A4D0; Thu, 20 Nov 2003 13:29:44 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4737E16A4CE for ; Thu, 20 Nov 2003 13:29:44 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 851AC43FAF for ; Thu, 20 Nov 2003 13:29:41 -0800 (PST) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.9/8.12.9) with ESMTP id hAKLTfXJ004072 for ; Thu, 20 Nov 2003 13:29:41 -0800 (PST) (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.9/8.12.9/Submit) id hAKLTeAm004069 for perforce@freebsd.org; Thu, 20 Nov 2003 13:29:40 -0800 (PST) (envelope-from jhb@freebsd.org) Date: Thu, 20 Nov 2003 13:29:40 -0800 (PST) Message-Id: <200311202129.hAKLTeAm004069@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Subject: PERFORCE change 42827 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Nov 2003 21:29:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=42827 Change 42827 by jhb@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 -__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 +#include #include +#include +#include #include -#include -#include #include -#include #include #include +#include #include -#include #ifdef __ia64__ #include #endif +#include #include "acpi.h" #include @@ -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 -__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 @@ -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 -__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 #include @@ -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) <<<