[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Add APERF/MPERF support for AMD processors



Starting with Family 0x10, model 10 processors, some AMD processors
will have support for the APERF/MPERF MSRs.  This patch adds the
checks necessary to support those MSRs.

It also makes the get_measured_perf function defined inside cpufreq.c
driver independent.  The max_freq is passed to the function by the caller
instead of being taking from the acpi-cpufreq only drv_data structure.

Signed-off-by: Mark Langsdorf <mark.langsdorf@xxxxxxx>

diff -r c4301c2c727d xen/arch/x86/acpi/cpufreq/cpufreq.c
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c       Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c       Thu Feb 25 00:54:28 2010 -0600
@@ -269,7 +269,7 @@
  * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
  * no meaning should be associated with absolute values of these MSRs.
  */
-static unsigned int get_measured_perf(unsigned int cpu, unsigned int flag)
+unsigned int get_measured_perf(unsigned int cpu, unsigned int flag, unsigned 
int max_freq)
 {
     struct cpufreq_policy *policy;    
     struct perf_pair readin, cur, *saved;
@@ -353,7 +353,7 @@
 
 #endif
 
-    retval = drv_data[policy->cpu]->max_freq * perf_percent / 100;
+    retval = max_freq * perf_percent / 100;
 
     return retval;
 }
diff -r c4301c2c727d xen/arch/x86/acpi/cpufreq/powernow.c
--- a/xen/arch/x86/acpi/cpufreq/powernow.c      Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/arch/x86/acpi/cpufreq/powernow.c      Thu Feb 25 00:54:28 2010 -0600
@@ -38,6 +38,7 @@
 #include <acpi/acpi.h>
 #include <acpi/cpufreq/cpufreq.h>
 
+#define CPUID_6_ECX_APERFMPERF_CAPABILITY       (0x1)
 #define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
 #define USE_HW_PSTATE           0x00000080
 #define HW_PSTATE_MASK          0x00000007
@@ -58,6 +59,8 @@
 };
 
 static struct powernow_cpufreq_data *drv_data[NR_CPUS];
+
+static struct cpufreq_driver powernow_cpufreq_driver;
 
 struct drv_cmd {
     unsigned int type;
@@ -159,6 +162,7 @@
     unsigned int result = 0;
     struct processor_performance *perf;
     u32 max_hw_pstate, hi = 0, lo = 0;
+    struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
 
     data = xmalloc(struct powernow_cpufreq_data);
     if (!data)
@@ -234,6 +238,14 @@
     if (result)
         goto err_freqfree;
 
+    /* Check for APERF/MPERF support in hardware */
+    if (c->cpuid_level >= 6) {
+        unsigned int ecx;
+        ecx = cpuid_ecx(6);
+        if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
+            powernow_cpufreq_driver.getavg = get_measured_perf;
+    }
+
     /*
      * the first call to ->target() should result in us actually
      * writing something to the appropriate registers.
diff -r c4301c2c727d xen/drivers/cpufreq/cpufreq_ondemand.c
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c    Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c    Thu Feb 25 00:54:28 2010 -0600
@@ -144,7 +144,7 @@
 
         load = 100 * (total_ns - idle_ns) / total_ns;
 
-        freq_avg = cpufreq_driver_getavg(j, GOV_GETAVG);
+        freq_avg = cpufreq_driver_getavg(j, GOV_GETAVG); 
 
         load_freq = load * freq_avg;
         if (load_freq > max_load_freq)
diff -r c4301c2c727d xen/drivers/cpufreq/utility.c
--- a/xen/drivers/cpufreq/utility.c     Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/drivers/cpufreq/utility.c     Thu Feb 25 00:54:28 2010 -0600
@@ -381,7 +381,9 @@
 
     if (cpufreq_driver->getavg)
     {
-        freq_avg = cpufreq_driver->getavg(cpu, flag);
+        freq_avg = cpufreq_driver->getavg(cpu, flag,
+                                         policy->cpuinfo.max_freq);
+
         if (freq_avg > 0)
             return freq_avg;
     }
diff -r c4301c2c727d xen/include/acpi/cpufreq/cpufreq.h
--- a/xen/include/acpi/cpufreq/cpufreq.h        Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/include/acpi/cpufreq/cpufreq.h        Thu Feb 25 00:54:28 2010 -0600
@@ -134,7 +134,8 @@
                      unsigned int target_freq,
                      unsigned int relation);
     unsigned int    (*get)(unsigned int cpu);
-    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
+    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag,
+                              unsigned int max_freq);
     int    (*exit)(struct cpufreq_policy *policy);
 };
 
diff -r c4301c2c727d xen/include/acpi/cpufreq/processor_perf.h
--- a/xen/include/acpi/cpufreq/processor_perf.h Fri Feb 26 17:09:50 2010 +0000
+++ b/xen/include/acpi/cpufreq/processor_perf.h Thu Feb 25 00:54:28 2010 -0600
@@ -9,6 +9,8 @@
 int get_cpu_id(u8);
 int powernow_cpufreq_init(void);
 unsigned int powernow_register_driver(void);
+unsigned int get_measured_perf(unsigned int cpu, unsigned int flag,
+                               unsigned int max_freq);
 
 void cpufreq_residency_update(unsigned int, uint8_t);
 void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t);


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.