WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH, v2] x86/cpufreq: fix turbo mode detection

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH, v2] x86/cpufreq: fix turbo mode detection
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Fri, 07 May 2010 09:39:11 +0100
Delivery-date: Fri, 07 May 2010 01:39:18 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
{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>

--- 2010-05-04.orig/xen/arch/x86/acpi/cpufreq/cpufreq.c 2010-05-06 
14:52:45.000000000 +0200
+++ 2010-05-04/xen/arch/x86/acpi/cpufreq/cpufreq.c      2010-05-07 
10:30:33.000000000 +0200
@@ -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)
@@ -377,6 +377,26 @@ static unsigned int get_cur_freq_on_cpu(
     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,
                                 struct acpi_cpufreq_data *data)
 {
@@ -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
--- 2010-05-04.orig/xen/arch/x86/acpi/cpufreq/powernow.c        2010-04-12 
11:28:20.000000000 +0200
+++ 2010-05-04/xen/arch/x86/acpi/cpufreq/powernow.c     2010-05-07 
10:30:26.000000000 +0200
@@ -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
--- 2010-05-04.orig/xen/include/acpi/cpufreq/cpufreq.h  2010-04-12 
11:28:20.000000000 +0200
+++ 2010-05-04/xen/include/acpi/cpufreq/cpufreq.h       2010-05-07 
10:22:20.000000000 +0200
@@ -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];
 


Attachment: cpufreq-turbo-detect.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH, v2] x86/cpufreq: fix turbo mode detection, Jan Beulich <=