Module Name: src Committed By: jruoho Date: Mon Aug 9 15:46:18 UTC 2010
Modified Files: src/sys/arch/x86/acpi: acpi_cpu_md.c src/sys/arch/x86/include: cpuvar.h src/sys/arch/x86/x86: cpu.c est.c src/sys/arch/xen/x86: cpu.c Log Message: Revert the previous changes to EST. The used hack had an obvious flaw: the acpicpu(4) driver should attach even if the existing frequency management code fails to attach, mainly because ACPI is the only proper way to deal with EST on new Intel system. Use a more drastic hack to deal with this: when acpicpu(4) attachs, it tears down any existing sysctl(8) controls and installs identical ones in place. Upon detachment, the initialization function of the existing EST is called. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/x86/acpi/acpi_cpu_md.c cvs rdiff -u -r1.36 -r1.37 src/sys/arch/x86/include/cpuvar.h cvs rdiff -u -r1.75 -r1.76 src/sys/arch/x86/x86/cpu.c cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x86/x86/est.c cvs rdiff -u -r1.47 -r1.48 src/sys/arch/xen/x86/cpu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/acpi/acpi_cpu_md.c diff -u src/sys/arch/x86/acpi/acpi_cpu_md.c:1.8 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.9 --- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.8 Mon Aug 9 13:41:39 2010 +++ src/sys/arch/x86/acpi/acpi_cpu_md.c Mon Aug 9 15:46:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_md.c,v 1.8 2010/08/09 13:41:39 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_md.c,v 1.9 2010/08/09 15:46:17 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.8 2010/08/09 13:41:39 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.9 2010/08/09 15:46:17 jruoho Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -47,6 +47,7 @@ static char native_idle_text[16]; void (*native_idle)(void) = NULL; +void (*native_cpu_freq_init)(int) = NULL; static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO); static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_PROTO); @@ -205,21 +206,97 @@ int acpicpu_md_pstate_start(void) { + const struct sysctlnode *fnode, *mnode, *rnode; + const char *str; + int rv; - cpu_freq_sysctl_get = acpicpu_md_pstate_sysctl_get; - cpu_freq_sysctl_set = acpicpu_md_pstate_sysctl_set; - cpu_freq_sysctl_all = acpicpu_md_pstate_sysctl_all; + switch (cpu_vendor) { + + case CPUVENDOR_INTEL: + str = "est"; + break; + + default: + return ENODEV; + } + + /* + * A kludge for backwards compatibility. + */ + native_cpu_freq_init = cpu_freq_init; + + if (cpu_freq_sysctllog != NULL) { + sysctl_teardown(&cpu_freq_sysctllog); + cpu_freq_sysctllog = NULL; + } + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, NULL, &rnode, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, + NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, &rnode, &mnode, + 0, CTLTYPE_NODE, str, NULL, + NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, &mnode, &fnode, + 0, CTLTYPE_NODE, "frequency", NULL, + NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, &fnode, &rnode, + CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL, + acpicpu_md_pstate_sysctl_set, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, &fnode, &rnode, + CTLFLAG_READONLY, CTLTYPE_INT, "current", NULL, + acpicpu_md_pstate_sysctl_get, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&cpu_freq_sysctllog, 0, &fnode, &rnode, + CTLFLAG_READONLY, CTLTYPE_STRING, "available", NULL, + acpicpu_md_pstate_sysctl_all, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; return 0; + +fail: + if (cpu_freq_sysctllog != NULL) { + sysctl_teardown(&cpu_freq_sysctllog); + cpu_freq_sysctllog = NULL; + } + + if (native_cpu_freq_init != NULL) + (*native_cpu_freq_init)(cpu_vendor); + + return rv; } int acpicpu_md_pstate_stop(void) { - cpu_freq_sysctl_get = NULL; - cpu_freq_sysctl_set = NULL; - cpu_freq_sysctl_all = NULL; + if (cpu_freq_sysctllog != NULL) { + sysctl_teardown(&cpu_freq_sysctllog); + cpu_freq_sysctllog = NULL; + } + + if (native_cpu_freq_init != NULL) + (*native_cpu_freq_init)(cpu_vendor); return 0; } @@ -238,7 +315,7 @@ * frequencies. In MP environments all CPUs * are mandated to support the same number of * P-states and each state must have identical - * parameters across CPUs. + * parameters across processors. */ sc = acpicpu_sc[ci->ci_acpiid]; Index: src/sys/arch/x86/include/cpuvar.h diff -u src/sys/arch/x86/include/cpuvar.h:1.36 src/sys/arch/x86/include/cpuvar.h:1.37 --- src/sys/arch/x86/include/cpuvar.h:1.36 Mon Aug 9 04:18:48 2010 +++ src/sys/arch/x86/include/cpuvar.h Mon Aug 9 15:46:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuvar.h,v 1.36 2010/08/09 04:18:48 jruoho Exp $ */ +/* $NetBSD: cpuvar.h,v 1.37 2010/08/09 15:46:17 jruoho Exp $ */ /*- * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc. @@ -142,9 +142,8 @@ int p4_get_bus_clock(struct cpu_info *); #endif -extern int (*cpu_freq_sysctl_get)(SYSCTLFN_PROTO); -extern int (*cpu_freq_sysctl_set)(SYSCTLFN_PROTO); -extern int (*cpu_freq_sysctl_all)(SYSCTLFN_PROTO); +extern void (*cpu_freq_init)(int); +extern struct sysctllog *cpu_freq_sysctllog; void cpu_get_tsc_freq(struct cpu_info *); void pat_init(struct cpu_info *); Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.75 src/sys/arch/x86/x86/cpu.c:1.76 --- src/sys/arch/x86/x86/cpu.c:1.75 Mon Aug 9 04:18:48 2010 +++ src/sys/arch/x86/x86/cpu.c Mon Aug 9 15:46:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.75 2010/08/09 04:18:48 jruoho Exp $ */ +/* $NetBSD: cpu.c,v 1.76 2010/08/09 15:46:17 jruoho Exp $ */ /*- * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.75 2010/08/09 04:18:48 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.76 2010/08/09 15:46:17 jruoho Exp $"); #include "opt_ddb.h" #include "opt_mpbios.h" /* for MPDEBUG */ @@ -185,9 +185,8 @@ static vaddr_t cmos_data_mapping; struct cpu_info *cpu_starting; -int (*cpu_freq_sysctl_get)(SYSCTLFN_PROTO) = NULL; -int (*cpu_freq_sysctl_set)(SYSCTLFN_PROTO) = NULL; -int (*cpu_freq_sysctl_all)(SYSCTLFN_PROTO) = NULL; +void (*cpu_freq_init)(int) = NULL; +struct sysctllog *cpu_freq_sysctllog = NULL; void cpu_hatch(void *); static void cpu_boot_secondary(struct cpu_info *ci); Index: src/sys/arch/x86/x86/est.c diff -u src/sys/arch/x86/x86/est.c:1.17 src/sys/arch/x86/x86/est.c:1.18 --- src/sys/arch/x86/x86/est.c:1.17 Mon Aug 9 04:18:49 2010 +++ src/sys/arch/x86/x86/est.c Mon Aug 9 15:46:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: est.c,v 1.17 2010/08/09 04:18:49 jruoho Exp $ */ +/* $NetBSD: est.c,v 1.18 2010/08/09 15:46:17 jruoho Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -81,7 +81,7 @@ /* #define EST_DEBUG */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.17 2010/08/09 04:18:49 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.18 2010/08/09 15:46:17 jruoho Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -998,72 +998,21 @@ static const struct fqlist *est_fqlist; /* not NULL if functional */ static uint16_t *fake_table; /* guessed est_cpu table */ -static char *freq_names; static struct fqlist fake_fqlist; static int est_node_target, est_node_current; static const char est_desc[] = "Enhanced SpeedStep"; static int lvendor, bus_clock; +static int est_sysctl_helper(SYSCTLFN_PROTO); static int est_init_once(void); static void est_init_main(int); -static int est_sysctl_helper(SYSCTLFN_PROTO); -static int est_sysctl_helper_get(SYSCTLFN_PROTO); -static int est_sysctl_helper_set(SYSCTLFN_PROTO); -static int est_sysctl_helper_all(SYSCTLFN_PROTO); - -static int -est_sysctl_helper_get(SYSCTLFN_ARGS) -{ - - if (cpu_freq_sysctl_get != NULL) - return (*cpu_freq_sysctl_get)(SYSCTLFN_CALL(rnode)); - - return est_sysctl_helper(SYSCTLFN_CALL(rnode)); -} - -static int -est_sysctl_helper_set(SYSCTLFN_ARGS) -{ - - if (cpu_freq_sysctl_set != NULL) - return (*cpu_freq_sysctl_set)(SYSCTLFN_CALL(rnode)); - - return est_sysctl_helper(SYSCTLFN_CALL(rnode)); -} - -static int -est_sysctl_helper_all(SYSCTLFN_ARGS) -{ - struct sysctlnode node; - int err; - - if (cpu_freq_sysctl_all != NULL) - return (*cpu_freq_sysctl_all)(SYSCTLFN_CALL(rnode)); - - if (freq_names == NULL) - return ENXIO; - - node = *rnode; - node.sysctl_data = freq_names; - - err = sysctl_lookup(SYSCTLFN_CALL(&node)); - - if (err != 0 || newp == NULL) - return err; - - return 0; -} - static int est_sysctl_helper(SYSCTLFN_ARGS) { struct sysctlnode node; int fq, oldfq, error; - if (freq_names == NULL) - return ENXIO; - if (est_fqlist == NULL) return EOPNOTSUPP; @@ -1137,6 +1086,7 @@ uint8_t crhi, crlo, crcur; int i, mv, rc; size_t len, freq_len; + char *freq_names; if (CPUID2FAMILY(curcpu()->ci_signature) == 15) bus_clock = p4_get_bus_clock(curcpu()); @@ -1311,45 +1261,54 @@ /* * Setup the sysctl sub-tree machdep.est.* */ - if ((rc = sysctl_createv(NULL, 0, NULL, &node, + if (cpu_freq_sysctllog != NULL) { + rc = EALREADY; + goto err; + } + + cpu_freq_init = est_init_main; + + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0) goto err; - if ((rc = sysctl_createv(NULL, 0, &node, &estnode, + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, &node, &estnode, 0, CTLTYPE_NODE, "est", NULL, NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; - if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode, + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, &estnode, &freqnode, 0, CTLTYPE_NODE, "frequency", NULL, NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; - if ((rc = sysctl_createv(NULL, 0, &freqnode, &node, + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, &freqnode, &node, EST_TARGET_CTLFLAG, CTLTYPE_INT, "target", NULL, - est_sysctl_helper_set, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) + est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; - est_node_target = node->sysctl_num; - if ((rc = sysctl_createv(NULL, 0, &freqnode, &node, + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, &freqnode, &node, 0, CTLTYPE_INT, "current", NULL, - est_sysctl_helper_get, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) + est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; - est_node_current = node->sysctl_num; - if ((rc = sysctl_createv(NULL, 0, &freqnode, &node, + if ((rc = sysctl_createv(&cpu_freq_sysctllog, 0, &freqnode, &node, CTLFLAG_READONLY, CTLTYPE_STRING, "available", NULL, - est_sysctl_helper_all, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) + NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0) goto err; return; err: free(freq_names, M_SYSCTLDATA); - freq_names = NULL; + + if (cpu_freq_sysctllog != NULL) + sysctl_teardown(&cpu_freq_sysctllog); + + cpu_freq_init = NULL; aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); } Index: src/sys/arch/xen/x86/cpu.c diff -u src/sys/arch/xen/x86/cpu.c:1.47 src/sys/arch/xen/x86/cpu.c:1.48 --- src/sys/arch/xen/x86/cpu.c:1.47 Sat Jul 24 00:45:56 2010 +++ src/sys/arch/xen/x86/cpu.c Mon Aug 9 15:46:18 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.47 2010/07/24 00:45:56 jym Exp $ */ +/* $NetBSD: cpu.c,v 1.48 2010/08/09 15:46:18 jruoho Exp $ */ /* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp */ /*- @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.47 2010/07/24 00:45:56 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.48 2010/08/09 15:46:18 jruoho Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -185,6 +185,9 @@ bool x86_mp_online; paddr_t mp_trampoline_paddr = MP_TRAMPOLINE; +void (*cpu_freq_init)(int) = NULL; +struct sysctllog *cpu_freq_sysctllog = NULL; + #if defined(MULTIPROCESSOR) void cpu_hatch(void *); static void cpu_boot_secondary(struct cpu_info *ci);