aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-04-09 08:52:43 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-04-09 08:52:43 +0100
commit002c5bcdbe112c70718ebc81ba95290210fa7f0d (patch)
tree79b6f996ecc5d1dd2d5f847acdf4525e4be768e2 /xen
parente136054cedf0b8d9395d35b8d3e5334eb514c47d (diff)
downloadxen-002c5bcdbe112c70718ebc81ba95290210fa7f0d.tar.gz
xen-002c5bcdbe112c70718ebc81ba95290210fa7f0d.tar.bz2
xen-002c5bcdbe112c70718ebc81ba95290210fa7f0d.zip
Refactor Xen Support for Intel Turbo Boost
Refactor the existing code that supports the Intel Turbo feature to move all the driver specific bits in the cpufreq driver. Create a tri-state interface for the Turbo feature that can distinguish amongst enabled Turbo, disabled Turbo, and processors that don't support Turbo at all. Signed-off-by: Mark Langsdorf <mark.langsdorf@amd.com>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/x86/acpi/cpufreq/cpufreq.c13
-rw-r--r--xen/drivers/acpi/pmstat.c7
-rw-r--r--xen/drivers/cpufreq/cpufreq_ondemand.c31
-rw-r--r--xen/drivers/cpufreq/utility.c25
-rw-r--r--xen/include/acpi/cpufreq/cpufreq.h14
-rw-r--r--xen/include/acpi/cpufreq/processor_perf.h1
-rw-r--r--xen/include/public/sysctl.h3
7 files changed, 53 insertions, 41 deletions
diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c
index 791cccd0d9..17776b4735 100644
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
@@ -410,6 +410,10 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
return -ENODEV;
}
+ if (policy->turbo == CPUFREQ_TURBO_DISABLED)
+ if (target_freq > policy->cpuinfo.second_max_freq)
+ target_freq = policy->cpuinfo.second_max_freq;
+
perf = data->acpi_data;
result = cpufreq_frequency_table_target(policy,
data->freq_table,
@@ -610,12 +614,19 @@ acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
break;
}
- /* Check for APERF/MPERF support in hardware */
+ /* 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");
+ }
}
/*
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
index f152000489..c88d000f63 100644
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -299,9 +299,8 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
&op->u.get_para.u.ondemand.sampling_rate_min,
&op->u.get_para.u.ondemand.sampling_rate,
&op->u.get_para.u.ondemand.up_threshold);
- op->u.get_para.u.ondemand.turbo_enabled =
- cpufreq_dbs_get_turbo_status(op->cpuid);
}
+ op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
return ret;
}
@@ -553,13 +552,13 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
case XEN_SYSCTL_pm_op_enable_turbo:
{
- cpufreq_dbs_enable_turbo(op->cpuid);
+ cpufreq_enable_turbo(op->cpuid);
break;
}
case XEN_SYSCTL_pm_op_disable_turbo:
{
- cpufreq_dbs_disable_turbo(op->cpuid);
+ cpufreq_disable_turbo(op->cpuid);
break;
}
diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
index 5728a8fbaf..dd4f6c45c1 100644
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
@@ -58,9 +58,6 @@ static struct dbs_tuners {
static struct timer dbs_timer[NR_CPUS];
-/* Turbo Mode */
-static int turbo_detected = 0;
-
int write_ondemand_sampling_rate(unsigned int sampling_rate)
{
if ( (sampling_rate > MAX_SAMPLING_RATE / MICROSECS(1)) ||
@@ -111,10 +108,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
policy = this_dbs_info->cur_policy;
max = policy->max;
- if (turbo_detected && !this_dbs_info->turbo_enabled) {
- if (max > policy->cpuinfo.second_max_freq)
- max = policy->cpuinfo.second_max_freq;
- }
if (unlikely(policy->resume)) {
__cpufreq_driver_target(policy, max,CPUFREQ_RELATION_H);
@@ -276,7 +269,6 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event)
} else
dbs_tuners_ins.sampling_rate = usr_sampling_rate;
}
- this_dbs_info->turbo_enabled = 1;
dbs_timer_init(this_dbs_info);
break;
@@ -353,13 +345,6 @@ struct cpufreq_governor cpufreq_gov_dbs = {
static int __init cpufreq_gov_dbs_init(void)
{
-#ifdef CONFIG_X86
- unsigned int eax = cpuid_eax(6);
- if ( eax & 0x2 ) {
- turbo_detected = 1;
- printk(XENLOG_INFO "Turbo Mode detected!\n");
- }
-#endif
return cpufreq_register_governor(&cpufreq_gov_dbs);
}
__initcall(cpufreq_gov_dbs_init);
@@ -404,19 +389,3 @@ void cpufreq_dbs_timer_resume(void)
}
}
}
-
-void cpufreq_dbs_enable_turbo(int cpuid)
-{
- per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 1;
-}
-
-void cpufreq_dbs_disable_turbo(int cpuid)
-{
- per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 0;
-}
-
-unsigned int cpufreq_dbs_get_turbo_status(int cpuid)
-{
- return turbo_detected && per_cpu(cpu_dbs_info, cpuid).turbo_enabled;
-}
-
diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c
index c730df951f..612f7e0919 100644
--- a/xen/drivers/cpufreq/utility.c
+++ b/xen/drivers/cpufreq/utility.c
@@ -394,6 +394,31 @@ int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag)
return policy->cur;
}
+void cpufreq_enable_turbo(int cpuid)
+{
+ struct cpufreq_policy *policy;
+
+ policy = cpufreq_cpu_policy[cpuid];
+ if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
+ policy->turbo = CPUFREQ_TURBO_ENABLED;
+}
+
+void cpufreq_disable_turbo(int cpuid)
+{
+ struct cpufreq_policy *policy;
+
+ policy = cpufreq_cpu_policy[cpuid];
+ if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
+ policy->turbo = CPUFREQ_TURBO_DISABLED;
+}
+
+int cpufreq_get_turbo_status(int cpuid)
+{
+ struct cpufreq_policy *policy;
+
+ policy = cpufreq_cpu_policy[cpuid];
+ return policy->turbo;
+}
/*********************************************************************
* POLICY *
diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h
index 4bdc74e0ac..53c9a0d314 100644
--- a/xen/include/acpi/cpufreq/cpufreq.h
+++ b/xen/include/acpi/cpufreq/cpufreq.h
@@ -55,6 +55,9 @@ struct cpufreq_policy {
unsigned int resume; /* flag for cpufreq 1st run
* S3 wakeup, hotplug cpu, etc */
+ int turbo; /* tristate flag: 0 for unsupported
+ * -1 for disable, 1 for enabled
+ * See CPUFREQ_TURBO_* below for defines */
};
extern struct cpufreq_policy *cpufreq_cpu_policy[NR_CPUS];
@@ -114,6 +117,14 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
#define USR_GETAVG 2
extern int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag);
+#define CPUFREQ_TURBO_DISABLED -1
+#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_get_turbo_status(int cpuid);
+
static __inline__ int
__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
{
@@ -241,7 +252,4 @@ int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
void cpufreq_dbs_timer_suspend(void);
void cpufreq_dbs_timer_resume(void);
-void cpufreq_dbs_enable_turbo(int cpuid);
-void cpufreq_dbs_disable_turbo(int cpuid);
-unsigned int cpufreq_dbs_get_turbo_status(int cpuid);
#endif /* __XEN_CPUFREQ_PM_H__ */
diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h
index 72b55ead82..40b3a7103b 100644
--- a/xen/include/acpi/cpufreq/processor_perf.h
+++ b/xen/include/acpi/cpufreq/processor_perf.h
@@ -9,7 +9,6 @@
int get_cpu_id(u8);
int powernow_cpufreq_init(void);
unsigned int powernow_register_driver(void);
-
void cpufreq_residency_update(unsigned int, uint8_t);
void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t);
int cpufreq_statistic_init(unsigned int);
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index eb9f1b8325..7255644286 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -283,7 +283,6 @@ struct xen_ondemand {
uint32_t sampling_rate;
uint32_t up_threshold;
- uint32_t turbo_enabled;
};
typedef struct xen_ondemand xen_ondemand_t;
@@ -319,6 +318,8 @@ struct xen_get_cpufreq_para {
struct xen_userspace userspace;
struct xen_ondemand ondemand;
} u;
+
+ int32_t turbo_enabled;
};
struct xen_set_cpufreq_gov {