[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86/cpufreq: fix turbo mode detection
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1273222010 -3600 # Node ID e1db99bab3ce4b0bba0086ae9988c00771d78dad # Parent 360032605d078ce21e6bad73c4995af0e875431a x86/cpufreq: fix turbo mode detection {acpi,powernow}_cpufreq_cpu_init() generally don't run on the CPU the policy they deal with is related to, hence using cpuid() directly works only as long as all CPUs in the system are identical (which admittedly is commonly the case). Further add a per-policy flag indicating the availability of APERF/MPERF MSRs, so that globally setting the .getavg accessor won't be a problem on heterogeneous configurations. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/acpi/cpufreq/cpufreq.c | 36 ++++++++++++++++++++++------------- xen/arch/x86/acpi/cpufreq/powernow.c | 35 ++++++++++++++++++++++------------ xen/include/acpi/cpufreq/cpufreq.h | 5 ++-- 3 files changed, 49 insertions(+), 27 deletions(-) diff -r 360032605d07 -r e1db99bab3ce xen/arch/x86/acpi/cpufreq/cpufreq.c --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri May 07 09:36:58 2010 +0100 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri May 07 09:46:50 2010 +0100 @@ -280,7 +280,7 @@ unsigned int get_measured_perf(unsigned return 0; policy = cpufreq_cpu_policy[cpu]; - if (!policy) + if (!policy || !policy->aperf_mperf) return 0; switch (flag) @@ -375,6 +375,26 @@ static unsigned int get_cur_freq_on_cpu( freq = extract_freq(get_cur_val(cpumask_of_cpu(cpu)), data); return freq; +} + +static void feature_detect(void *info) +{ + struct cpufreq_policy *policy = info; + unsigned int eax, ecx; + + ecx = cpuid_ecx(6); + if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) { + policy->aperf_mperf = 1; + acpi_cpufreq_driver.getavg = get_measured_perf; + } + + eax = cpuid_eax(6); + if (eax & 0x2) { + policy->turbo = CPUFREQ_TURBO_ENABLED; + if (cpufreq_verbose) + printk(XENLOG_INFO "CPU%u: Turbo Mode detected and enabled\n", + smp_processor_id()); + } } static unsigned int check_freqs(cpumask_t mask, unsigned int freq, @@ -615,18 +635,8 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol /* Check for APERF/MPERF support in hardware * also check for boost support */ - if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) { - unsigned int ecx; - unsigned int eax; - ecx = cpuid_ecx(6); - if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) - acpi_cpufreq_driver.getavg = get_measured_perf; - eax = cpuid_eax(6); - if ( eax & 0x2 ) { - policy->turbo = CPUFREQ_TURBO_ENABLED; - printk(XENLOG_INFO "Turbo Mode detected and enabled!\n"); - } - } + if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) + on_selected_cpus(cpumask_of(cpu), feature_detect, policy, 1); /* * the first call to ->target() should result in us actually diff -r 360032605d07 -r e1db99bab3ce xen/arch/x86/acpi/cpufreq/powernow.c --- a/xen/arch/x86/acpi/cpufreq/powernow.c Fri May 07 09:36:58 2010 +0100 +++ b/xen/arch/x86/acpi/cpufreq/powernow.c Fri May 07 09:46:50 2010 +0100 @@ -165,6 +165,27 @@ static int powernow_cpufreq_verify(struc return cpufreq_frequency_table_verify(policy, data->freq_table); } +static void feature_detect(void *info) +{ + struct cpufreq_policy *policy = info; + unsigned int ecx, edx; + + ecx = cpuid_ecx(6); + if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) { + policy->aperf_mperf = 1; + powernow_cpufreq_driver.getavg = get_measured_perf; + } + + edx = cpuid_edx(CPUID_FREQ_VOLT_CAPABILITIES); + if ((edx & CPB_CAPABLE) == CPB_CAPABLE) { + policy->turbo = CPUFREQ_TURBO_ENABLED; + if (cpufreq_verbose) + printk(XENLOG_INFO + "CPU%u: Core Boost/Turbo detected and enabled\n", + smp_processor_id()); + } +} + static int powernow_cpufreq_cpu_init(struct cpufreq_policy *policy) { unsigned int i; @@ -250,18 +271,8 @@ static int powernow_cpufreq_cpu_init(str if (result) goto err_freqfree; - if (c->cpuid_level >= 6) { - unsigned int edx; - unsigned int ecx; - ecx = cpuid_ecx(6); - if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) - powernow_cpufreq_driver.getavg = get_measured_perf; - edx = cpuid_edx(CPUID_FREQ_VOLT_CAPABILITIES); - if ((edx & CPB_CAPABLE) == CPB_CAPABLE) { - policy->turbo = CPUFREQ_TURBO_ENABLED; - printk(XENLOG_INFO "Core Boost/Turbo detected and enabled\n"); - } - } + if (c->cpuid_level >= 6) + on_selected_cpus(cpumask_of(cpu), feature_detect, policy, 1); /* * the first call to ->target() should result in us actually diff -r 360032605d07 -r e1db99bab3ce xen/include/acpi/cpufreq/cpufreq.h --- a/xen/include/acpi/cpufreq/cpufreq.h Fri May 07 09:36:58 2010 +0100 +++ b/xen/include/acpi/cpufreq/cpufreq.h Fri May 07 09:46:50 2010 +0100 @@ -52,11 +52,12 @@ struct cpufreq_policy { * governors are used */ struct cpufreq_governor *governor; - unsigned int resume; /* flag for cpufreq 1st run + bool_t resume; /* flag for cpufreq 1st run * S3 wakeup, hotplug cpu, etc */ - int turbo; /* tristate flag: 0 for unsupported + s8 turbo; /* tristate flag: 0 for unsupported * -1 for disable, 1 for enabled * See CPUFREQ_TURBO_* below for defines */ + bool_t aperf_mperf; /* CPU has APERF/MPERF MSRs */ }; extern struct cpufreq_policy *cpufreq_cpu_policy[NR_CPUS]; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |