# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1270799563 -3600
# Node ID 6c3db6c83a02b73b8c1ab281472d207d7ec3c2d5
# Parent f12db0ad5f450c7c51d736f5db8ffbf5dbfb8c25
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@xxxxxxx>
---
tools/libxc/xc_pm.c | 1
tools/libxc/xenctrl.h | 2 +
tools/misc/xenpm.c | 18 +++++++++++++----
xen/arch/x86/acpi/cpufreq/cpufreq.c | 13 +++++++++++-
xen/drivers/acpi/pmstat.c | 9 +++-----
xen/drivers/cpufreq/cpufreq_ondemand.c | 31 ------------------------------
xen/drivers/cpufreq/utility.c | 25 ++++++++++++++++++++++++
xen/include/acpi/cpufreq/cpufreq.h | 14 ++++++++++---
xen/include/acpi/cpufreq/processor_perf.h | 1
xen/include/public/sysctl.h | 3 +-
10 files changed, 71 insertions(+), 46 deletions(-)
diff -r f12db0ad5f45 -r 6c3db6c83a02 tools/libxc/xc_pm.c
--- a/tools/libxc/xc_pm.c Thu Apr 08 16:11:17 2010 +0100
+++ b/tools/libxc/xc_pm.c Fri Apr 09 08:52:43 2010 +0100
@@ -247,6 +247,7 @@ int xc_get_cpufreq_para(int xc_handle, i
user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
user_para->scaling_max_freq = sys_para->scaling_max_freq;
user_para->scaling_min_freq = sys_para->scaling_min_freq;
+ user_para->turbo_enabled = sys_para->turbo_enabled;
memcpy(user_para->scaling_driver,
sys_para->scaling_driver, CPUFREQ_NAME_LEN);
diff -r f12db0ad5f45 -r 6c3db6c83a02 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Apr 08 16:11:17 2010 +0100
+++ b/tools/libxc/xenctrl.h Fri Apr 09 08:52:43 2010 +0100
@@ -1292,6 +1292,8 @@ struct xc_get_cpufreq_para {
xc_userspace_t userspace;
xc_ondemand_t ondemand;
} u;
+
+ int32_t turbo_enabled;
};
int xc_get_cpufreq_para(int xc_handle, int cpuid,
diff -r f12db0ad5f45 -r 6c3db6c83a02 tools/misc/xenpm.c
--- a/tools/misc/xenpm.c Thu Apr 08 16:11:17 2010 +0100
+++ b/tools/misc/xenpm.c Fri Apr 09 08:52:43 2010 +0100
@@ -29,6 +29,10 @@
#include <sys/time.h>
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+#define CPUFREQ_TURBO_DISABLED -1
+#define CPUFREQ_TURBO_UNSUPPORTED 0
+#define CPUFREQ_TURBO_ENABLED 1
static int xc_fd;
static int max_cpu_nr;
@@ -62,8 +66,8 @@ void show_help(void)
" set-max-cstate <num> set the C-State limitation
(<num> >= 0)\n"
" start [seconds] start collect Cx/Px
statistics,\n"
" output after CTRL-C or
SIGINT or several seconds.\n"
- " enable-turbo-mode [cpuid] enable Turbo Mode in DBS
governor.\n"
- " disable-turbo-mode [cpuid] disable Turbo Mode in DBS
governor.\n"
+ " enable-turbo-mode [cpuid] enable Turbo Mode for
processors that support it.\n"
+ " disable-turbo-mode [cpuid] disable Turbo Mode for
processors that support it.\n"
);
}
/* wrapper function */
@@ -529,8 +533,6 @@ static void print_cpufreq_para(int cpuid
p_cpufreq->u.ondemand.sampling_rate);
printf(" up_threshold : %u\n",
p_cpufreq->u.ondemand.up_threshold);
- printf(" turbo mode : %s\n",
- p_cpufreq->u.ondemand.turbo_enabled ? "enabled" : "disabled");
}
printf("scaling_avail_freq :");
@@ -546,6 +548,13 @@ static void print_cpufreq_para(int cpuid
p_cpufreq->scaling_max_freq,
p_cpufreq->scaling_min_freq,
p_cpufreq->scaling_cur_freq);
+ if (p_cpufreq->turbo_enabled != CPUFREQ_TURBO_UNSUPPORTED) {
+ printf("turbo mode : ");
+ if (p_cpufreq->turbo_enabled == CPUFREQ_TURBO_ENABLED)
+ printf("enabled\n");
+ else
+ printf("disabled\n");
+ }
printf("\n");
}
@@ -561,6 +570,7 @@ static int show_cpufreq_para_by_cpuid(in
p_cpufreq->affected_cpus = NULL;
p_cpufreq->scaling_available_frequencies = NULL;
p_cpufreq->scaling_available_governors = NULL;
+ p_cpufreq->turbo_enabled = 0;
do
{
diff -r f12db0ad5f45 -r 6c3db6c83a02 xen/arch/x86/acpi/cpufreq/cpufreq.c
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri Apr 09 08:52:43 2010 +0100
@@ -410,6 +410,10 @@ static int acpi_cpufreq_target(struct cp
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_pol
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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/drivers/acpi/pmstat.c
--- a/xen/drivers/acpi/pmstat.c Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/drivers/acpi/pmstat.c Fri Apr 09 08:52:43 2010 +0100
@@ -299,9 +299,8 @@ static int get_cpufreq_para(struct xen_s
&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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/drivers/cpufreq/cpufreq_ondemand.c
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Fri Apr 09 08:52:43 2010 +0100
@@ -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
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_
} 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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/drivers/cpufreq/utility.c
--- a/xen/drivers/cpufreq/utility.c Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/drivers/cpufreq/utility.c Fri Apr 09 08:52:43 2010 +0100
@@ -394,6 +394,31 @@ int cpufreq_driver_getavg(unsigned int c
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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/include/acpi/cpufreq/cpufreq.h
--- a/xen/include/acpi/cpufreq/cpufreq.h Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/include/acpi/cpufreq/cpufreq.h Fri Apr 09 08:52:43 2010 +0100
@@ -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];
@@ -113,6 +116,14 @@ extern int __cpufreq_driver_target(struc
#define GOV_GETAVG 1
#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 @@ void cpufreq_dbs_timer_suspend(void);
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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/include/acpi/cpufreq/processor_perf.h
--- a/xen/include/acpi/cpufreq/processor_perf.h Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/include/acpi/cpufreq/processor_perf.h Fri Apr 09 08:52:43 2010 +0100
@@ -9,7 +9,6 @@ int get_cpu_id(u8);
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 -r f12db0ad5f45 -r 6c3db6c83a02 xen/include/public/sysctl.h
--- a/xen/include/public/sysctl.h Thu Apr 08 16:11:17 2010 +0100
+++ b/xen/include/public/sysctl.h Fri Apr 09 08:52:43 2010 +0100
@@ -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 {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|