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

[Xen-changelog] [xen-unstable] x86, cpufreq: Change powernow's CPB status immediately


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Sat, 23 Jun 2012 05:22:15 +0000
  • Delivery-date: Sat, 23 Jun 2012 05:22:21 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Boris Ostrovsky <boris.ostrovsky@xxxxxxx>
# Date 1340028523 -3600
# Node ID c272cfe25bea00375fb65c339926c83b6e830230
# Parent  9dffb1864f2c516794a90a8ceece3eb044dab212
x86, cpufreq: Change powernow's CPB status immediately

When command to modify turbo mode (CPB on AMD processors) comes
in the actual change happens later, when P-state transition is
requested. There is no time limit on when this transition will
occur and therefore change in CPB state may take long time from
the moment when command to toggle it is issued.

This patch makes CPB mode change happen immediately when request
is made.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 9dffb1864f2c -r c272cfe25bea xen/arch/x86/acpi/cpufreq/powernow.c
--- a/xen/arch/x86/acpi/cpufreq/powernow.c      Thu Jun 14 16:05:42 2012 +0100
+++ b/xen/arch/x86/acpi/cpufreq/powernow.c      Mon Jun 18 15:08:43 2012 +0100
@@ -68,16 +68,37 @@ static void transition_pstate(void *drvc
     struct drv_cmd *cmd;
     cmd = (struct drv_cmd *) drvcmd;
 
-    if (cmd->turbo != CPUFREQ_TURBO_UNSUPPORTED) {
+
+    wrmsrl(MSR_PSTATE_CTRL, cmd->val);
+}
+
+static void update_cpb(void *data)
+{
+    struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
+
+    if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) {
         uint64_t msr_content;
+ 
         rdmsrl(MSR_K8_HWCR, msr_content);
-        if (cmd->turbo == CPUFREQ_TURBO_ENABLED)
+
+        if (policy->turbo == CPUFREQ_TURBO_ENABLED)
             msr_content &= ~MSR_HWCR_CPBDIS_MASK;
         else
             msr_content |= MSR_HWCR_CPBDIS_MASK; 
+
         wrmsrl(MSR_K8_HWCR, msr_content);
     }
-    wrmsrl(MSR_PSTATE_CTRL, cmd->val);
+}
+
+static int powernow_cpufreq_update (int cpuid,
+                                    struct cpufreq_policy *policy)
+{
+    if (!cpumask_test_cpu(cpuid, &cpu_online_map))
+        return -EINVAL;
+
+    on_selected_cpus(cpumask_of(cpuid), update_cpb, policy, 1);
+
+    return 0;
 }
 
 static int powernow_cpufreq_target(struct cpufreq_policy *policy,
@@ -300,7 +321,8 @@ static struct cpufreq_driver powernow_cp
     .verify = powernow_cpufreq_verify,
     .target = powernow_cpufreq_target,
     .init   = powernow_cpufreq_cpu_init,
-    .exit   = powernow_cpufreq_cpu_exit
+    .exit   = powernow_cpufreq_cpu_exit,
+    .update = powernow_cpufreq_update
 };
 
 unsigned int __init powernow_register_driver()
diff -r 9dffb1864f2c -r c272cfe25bea xen/drivers/acpi/pmstat.c
--- a/xen/drivers/acpi/pmstat.c Thu Jun 14 16:05:42 2012 +0100
+++ b/xen/drivers/acpi/pmstat.c Mon Jun 18 15:08:43 2012 +0100
@@ -494,13 +494,13 @@ int do_pm_op(struct xen_sysctl_pm_op *op
 
     case XEN_SYSCTL_pm_op_enable_turbo:
     {
-        cpufreq_enable_turbo(op->cpuid);
+        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
         break;
     }
 
     case XEN_SYSCTL_pm_op_disable_turbo:
     {
-        cpufreq_disable_turbo(op->cpuid);
+        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
         break;
     }
 
diff -r 9dffb1864f2c -r c272cfe25bea xen/drivers/cpufreq/utility.c
--- a/xen/drivers/cpufreq/utility.c     Thu Jun 14 16:05:42 2012 +0100
+++ b/xen/drivers/cpufreq/utility.c     Mon Jun 18 15:08:43 2012 +0100
@@ -390,23 +390,38 @@ int cpufreq_driver_getavg(unsigned int c
     return policy->cur;
 }
 
-void cpufreq_enable_turbo(int cpuid)
+int cpufreq_update_turbo(int cpuid, int new_state)
 {
     struct cpufreq_policy *policy;
+    int curr_state;
+    int ret = 0;
+
+    if (new_state != CPUFREQ_TURBO_ENABLED &&
+        new_state != CPUFREQ_TURBO_DISABLED)
+        return -EINVAL;
 
     policy = per_cpu(cpufreq_cpu_policy, cpuid);
-    if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
-        policy->turbo = CPUFREQ_TURBO_ENABLED;
+    if (!policy)
+        return -EACCES;
+
+    if (policy->turbo == CPUFREQ_TURBO_UNSUPPORTED)
+        return -EOPNOTSUPP;
+
+    curr_state = policy->turbo;
+    if (curr_state == new_state)
+        return 0;
+
+    policy->turbo = new_state;
+    if (cpufreq_driver->update)
+    {
+        ret = cpufreq_driver->update(cpuid, policy);
+        if (ret)
+            policy->turbo = curr_state;
+    }
+
+    return ret;
 }
 
-void cpufreq_disable_turbo(int cpuid)
-{
-    struct cpufreq_policy *policy;
-
-    policy = per_cpu(cpufreq_cpu_policy, cpuid);
-    if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
-        policy->turbo = CPUFREQ_TURBO_DISABLED;
-}
 
 int cpufreq_get_turbo_status(int cpuid)
 {
diff -r 9dffb1864f2c -r c272cfe25bea xen/include/acpi/cpufreq/cpufreq.h
--- a/xen/include/acpi/cpufreq/cpufreq.h        Thu Jun 14 16:05:42 2012 +0100
+++ b/xen/include/acpi/cpufreq/cpufreq.h        Mon Jun 18 15:08:43 2012 +0100
@@ -124,8 +124,7 @@ extern int cpufreq_driver_getavg(unsigne
 #define CPUFREQ_TURBO_UNSUPPORTED   0
 #define CPUFREQ_TURBO_ENABLED       1
 
-extern void cpufreq_enable_turbo(int cpuid);
-extern void cpufreq_disable_turbo(int cpuid);
+extern int cpufreq_update_turbo(int cpuid, int new_state);
 extern int cpufreq_get_turbo_status(int cpuid);
 
 static __inline__ int 
@@ -146,6 +145,7 @@ struct cpufreq_driver {
     char   name[CPUFREQ_NAME_LEN];
     int    (*init)(struct cpufreq_policy *policy);
     int    (*verify)(struct cpufreq_policy *policy);
+    int    (*update)(int cpuid, struct cpufreq_policy *policy);
     int    (*target)(struct cpufreq_policy *policy,
                      unsigned int target_freq,
                      unsigned int relation);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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