debuggers.hg
changeset 20954:a06e9def02bb
xenpm: Allow user to enable/disable dbs governor turbo mode.
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Feb 08 08:48:40 2010 +0000 (2010-02-08) |
parents | 4f2d9156424d |
children | 12fc55dffb6b |
files | tools/libxc/xc_pm.c tools/libxc/xenctrl.h tools/misc/xenpm.c xen/drivers/acpi/pmstat.c xen/drivers/cpufreq/cpufreq_ondemand.c xen/drivers/cpufreq/utility.c xen/include/acpi/cpufreq/cpufreq.h xen/include/public/sysctl.h |
line diff
1.1 --- a/tools/libxc/xc_pm.c Mon Feb 08 08:43:25 2010 +0000 1.2 +++ b/tools/libxc/xc_pm.c Mon Feb 08 08:48:40 2010 +0000 1.3 @@ -425,3 +425,28 @@ int xc_set_cpuidle_max_cstate(int xc_han 1.4 return do_sysctl(xc_handle, &sysctl); 1.5 } 1.6 1.7 +int xc_enable_turbo(int xc_handle, int cpuid) 1.8 +{ 1.9 + DECLARE_SYSCTL; 1.10 + 1.11 + if ( xc_handle < 0 ) 1.12 + return -EINVAL; 1.13 + 1.14 + sysctl.cmd = XEN_SYSCTL_pm_op; 1.15 + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_enable_turbo; 1.16 + sysctl.u.pm_op.cpuid = cpuid; 1.17 + return do_sysctl(xc_handle, &sysctl); 1.18 +} 1.19 + 1.20 +int xc_disable_turbo(int xc_handle, int cpuid) 1.21 +{ 1.22 + DECLARE_SYSCTL; 1.23 + 1.24 + if ( xc_handle < 0 ) 1.25 + return -EINVAL; 1.26 + 1.27 + sysctl.cmd = XEN_SYSCTL_pm_op; 1.28 + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_disable_turbo; 1.29 + sysctl.u.pm_op.cpuid = cpuid; 1.30 + return do_sysctl(xc_handle, &sysctl); 1.31 +}
2.1 --- a/tools/libxc/xenctrl.h Mon Feb 08 08:43:25 2010 +0000 2.2 +++ b/tools/libxc/xenctrl.h Mon Feb 08 08:48:40 2010 +0000 2.3 @@ -1312,6 +1312,8 @@ int xc_get_vcpu_migration_delay(int xc_h 2.4 int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value); 2.5 int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value); 2.6 2.7 +int xc_enable_turbo(int xc_handle, int cpuid); 2.8 +int xc_disable_turbo(int xc_handle, int cpuid); 2.9 /** 2.10 * tmem operations 2.11 */
3.1 --- a/tools/misc/xenpm.c Mon Feb 08 08:43:25 2010 +0000 3.2 +++ b/tools/misc/xenpm.c Mon Feb 08 08:48:40 2010 +0000 3.3 @@ -62,6 +62,8 @@ void show_help(void) 3.4 " set-max-cstate <num> set the C-State limitation (<num> >= 0)\n" 3.5 " start [seconds] start collect Cx/Px statistics,\n" 3.6 " output after CTRL-C or SIGINT or several seconds.\n" 3.7 + " enable-turbo-mode [cpuid] enable Turbo Mode in DBS governor.\n" 3.8 + " disable-turbo-mode [cpuid] disable Turbo Mode in DBS governor.\n" 3.9 ); 3.10 } 3.11 /* wrapper function */ 3.12 @@ -527,6 +529,8 @@ static void print_cpufreq_para(int cpuid 3.13 p_cpufreq->u.ondemand.sampling_rate); 3.14 printf(" up_threshold : %u\n", 3.15 p_cpufreq->u.ondemand.up_threshold); 3.16 + printf(" turbo mode : %s\n", 3.17 + p_cpufreq->u.ondemand.turbo_enabled ? "enabled" : "disabled"); 3.18 } 3.19 3.20 printf("scaling_avail_freq :"); 3.21 @@ -951,6 +955,50 @@ void set_max_cstate_func(int argc, char 3.22 return; 3.23 } 3.24 3.25 +void enable_turbo_mode(int argc, char *argv[]) 3.26 +{ 3.27 + int cpuid = -1; 3.28 + 3.29 + if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 ) 3.30 + cpuid = -1; 3.31 + 3.32 + if ( cpuid >= max_cpu_nr ) 3.33 + cpuid = -1; 3.34 + 3.35 + if ( cpuid < 0 ) 3.36 + { 3.37 + /* enable turbo modes on all cpus, 3.38 + * only make effects on dbs governor */ 3.39 + int i; 3.40 + for ( i = 0; i < max_cpu_nr; i++ ) 3.41 + xc_enable_turbo(xc_fd, i); 3.42 + } 3.43 + else 3.44 + xc_enable_turbo(xc_fd, cpuid); 3.45 +} 3.46 + 3.47 +void disable_turbo_mode(int argc, char *argv[]) 3.48 +{ 3.49 + int cpuid = -1; 3.50 + 3.51 + if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 ) 3.52 + cpuid = -1; 3.53 + 3.54 + if ( cpuid >= max_cpu_nr ) 3.55 + cpuid = -1; 3.56 + 3.57 + if ( cpuid < 0 ) 3.58 + { 3.59 + /* disable turbo modes on all cpus, 3.60 + * only make effects on dbs governor */ 3.61 + int i; 3.62 + for ( i = 0; i < max_cpu_nr; i++ ) 3.63 + xc_disable_turbo(xc_fd, i); 3.64 + } 3.65 + else 3.66 + xc_disable_turbo(xc_fd, cpuid); 3.67 +} 3.68 + 3.69 struct { 3.70 const char *name; 3.71 void (*function)(int argc, char *argv[]); 3.72 @@ -971,6 +1019,8 @@ struct { 3.73 { "get-vcpu-migration-delay", get_vcpu_migration_delay_func}, 3.74 { "set-vcpu-migration-delay", set_vcpu_migration_delay_func}, 3.75 { "set-max-cstate", set_max_cstate_func}, 3.76 + { "enable-turbo-mode", enable_turbo_mode }, 3.77 + { "disable-turbo-mode", disable_turbo_mode }, 3.78 }; 3.79 3.80 int main(int argc, char *argv[])
4.1 --- a/xen/drivers/acpi/pmstat.c Mon Feb 08 08:43:25 2010 +0000 4.2 +++ b/xen/drivers/acpi/pmstat.c Mon Feb 08 08:48:40 2010 +0000 4.3 @@ -298,7 +298,9 @@ static int get_cpufreq_para(struct xen_s 4.4 &op->u.get_para.u.ondemand.sampling_rate_max, 4.5 &op->u.get_para.u.ondemand.sampling_rate_min, 4.6 &op->u.get_para.u.ondemand.sampling_rate, 4.7 - &op->u.get_para.u.ondemand.up_threshold); 4.8 + &op->u.get_para.u.ondemand.up_threshold); 4.9 + op->u.get_para.u.ondemand.turbo_enabled = 4.10 + cpufreq_dbs_get_turbo_status(op->cpuid); 4.11 } 4.12 4.13 return ret; 4.14 @@ -549,6 +551,18 @@ int do_pm_op(struct xen_sysctl_pm_op *op 4.15 break; 4.16 } 4.17 4.18 + case XEN_SYSCTL_pm_op_enable_turbo: 4.19 + { 4.20 + cpufreq_dbs_enable_turbo(op->cpuid); 4.21 + break; 4.22 + } 4.23 + 4.24 + case XEN_SYSCTL_pm_op_disable_turbo: 4.25 + { 4.26 + cpufreq_dbs_disable_turbo(op->cpuid); 4.27 + break; 4.28 + } 4.29 + 4.30 default: 4.31 printk("not defined sub-hypercall @ do_pm_op\n"); 4.32 ret = -ENOSYS;
5.1 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Mon Feb 08 08:43:25 2010 +0000 5.2 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Mon Feb 08 08:48:40 2010 +0000 5.3 @@ -58,6 +58,9 @@ static struct dbs_tuners { 5.4 5.5 static struct timer dbs_timer[NR_CPUS]; 5.6 5.7 +/* Turbo Mode */ 5.8 +static int turbo_detected = 0; 5.9 + 5.10 int write_ondemand_sampling_rate(unsigned int sampling_rate) 5.11 { 5.12 if ( (sampling_rate > MAX_SAMPLING_RATE / MICROSECS(1)) || 5.13 @@ -100,15 +103,21 @@ static void dbs_check_cpu(struct cpu_dbs 5.14 uint64_t cur_ns, total_ns; 5.15 uint64_t max_load_freq = 0; 5.16 struct cpufreq_policy *policy; 5.17 + unsigned int max; 5.18 unsigned int j; 5.19 5.20 if (!this_dbs_info->enable) 5.21 return; 5.22 5.23 policy = this_dbs_info->cur_policy; 5.24 + max = policy->max; 5.25 + if (turbo_detected && !this_dbs_info->turbo_enabled) { 5.26 + if (max > policy->cpuinfo.second_max_freq) 5.27 + max = policy->cpuinfo.second_max_freq; 5.28 + } 5.29 5.30 if (unlikely(policy->resume)) { 5.31 - __cpufreq_driver_target(policy, policy->max,CPUFREQ_RELATION_H); 5.32 + __cpufreq_driver_target(policy, max,CPUFREQ_RELATION_H); 5.33 return; 5.34 } 5.35 5.36 @@ -145,9 +154,9 @@ static void dbs_check_cpu(struct cpu_dbs 5.37 /* Check for frequency increase */ 5.38 if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { 5.39 /* if we are already at full speed then break out early */ 5.40 - if (policy->cur == policy->max) 5.41 + if (policy->cur == max) 5.42 return; 5.43 - __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); 5.44 + __cpufreq_driver_target(policy, max, CPUFREQ_RELATION_H); 5.45 return; 5.46 } 5.47 5.48 @@ -265,6 +274,7 @@ int cpufreq_governor_dbs(struct cpufreq_ 5.49 } else 5.50 dbs_tuners_ins.sampling_rate = usr_sampling_rate; 5.51 } 5.52 + this_dbs_info->turbo_enabled = 1; 5.53 dbs_timer_init(this_dbs_info); 5.54 5.55 break; 5.56 @@ -335,6 +345,11 @@ struct cpufreq_governor cpufreq_gov_dbs 5.57 5.58 static int __init cpufreq_gov_dbs_init(void) 5.59 { 5.60 + unsigned int eax = cpuid_eax(6); 5.61 + if ( eax & 0x2 ) { 5.62 + turbo_detected = 1; 5.63 + printk(XENLOG_INFO "Turbo Mode detected!\n"); 5.64 + } 5.65 return cpufreq_register_governor(&cpufreq_gov_dbs); 5.66 } 5.67 __initcall(cpufreq_gov_dbs_init); 5.68 @@ -379,3 +394,19 @@ void cpufreq_dbs_timer_resume(void) 5.69 } 5.70 } 5.71 } 5.72 + 5.73 +void cpufreq_dbs_enable_turbo(int cpuid) 5.74 +{ 5.75 + per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 1; 5.76 +} 5.77 + 5.78 +void cpufreq_dbs_disable_turbo(int cpuid) 5.79 +{ 5.80 + per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 0; 5.81 +} 5.82 + 5.83 +unsigned int cpufreq_dbs_get_turbo_status(int cpuid) 5.84 +{ 5.85 + return turbo_detected && per_cpu(cpu_dbs_info, cpuid).turbo_enabled; 5.86 +} 5.87 +
6.1 --- a/xen/drivers/cpufreq/utility.c Mon Feb 08 08:43:25 2010 +0000 6.2 +++ b/xen/drivers/cpufreq/utility.c Mon Feb 08 08:48:40 2010 +0000 6.3 @@ -208,6 +208,7 @@ int cpufreq_frequency_table_cpuinfo(stru 6.4 { 6.5 unsigned int min_freq = ~0; 6.6 unsigned int max_freq = 0; 6.7 + unsigned int second_max_freq = 0; 6.8 unsigned int i; 6.9 6.10 for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { 6.11 @@ -219,9 +220,21 @@ int cpufreq_frequency_table_cpuinfo(stru 6.12 if (freq > max_freq) 6.13 max_freq = freq; 6.14 } 6.15 + for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { 6.16 + unsigned int freq = table[i].frequency; 6.17 + if (freq == CPUFREQ_ENTRY_INVALID || freq == max_freq) 6.18 + continue; 6.19 + if (freq > second_max_freq) 6.20 + second_max_freq = freq; 6.21 + } 6.22 + if (second_max_freq == 0) 6.23 + second_max_freq = max_freq; 6.24 + printk(XENLOG_INFO "max_freq: %u second_max_freq: %u\n", 6.25 + max_freq, second_max_freq); 6.26 6.27 policy->min = policy->cpuinfo.min_freq = min_freq; 6.28 policy->max = policy->cpuinfo.max_freq = max_freq; 6.29 + policy->cpuinfo.second_max_freq = second_max_freq; 6.30 6.31 if (policy->min == ~0) 6.32 return -EINVAL;
7.1 --- a/xen/include/acpi/cpufreq/cpufreq.h Mon Feb 08 08:43:25 2010 +0000 7.2 +++ b/xen/include/acpi/cpufreq/cpufreq.h Mon Feb 08 08:48:40 2010 +0000 7.3 @@ -33,6 +33,7 @@ struct acpi_cpufreq_data { 7.4 7.5 struct cpufreq_cpuinfo { 7.6 unsigned int max_freq; 7.7 + unsigned int second_max_freq; /* P1 if Turbo Mode is on */ 7.8 unsigned int min_freq; 7.9 unsigned int transition_latency; /* in 10^(-9) s = nanoseconds */ 7.10 }; 7.11 @@ -222,6 +223,7 @@ struct cpu_dbs_info_s { 7.12 int cpu; 7.13 unsigned int enable:1; 7.14 unsigned int stoppable:1; 7.15 + unsigned int turbo_enabled:1; 7.16 }; 7.17 7.18 int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event); 7.19 @@ -236,4 +238,8 @@ int write_userspace_scaling_setspeed(uns 7.20 7.21 void cpufreq_dbs_timer_suspend(void); 7.22 void cpufreq_dbs_timer_resume(void); 7.23 + 7.24 +void cpufreq_dbs_enable_turbo(int cpuid); 7.25 +void cpufreq_dbs_disable_turbo(int cpuid); 7.26 +unsigned int cpufreq_dbs_get_turbo_status(int cpuid); 7.27 #endif /* __XEN_CPUFREQ_PM_H__ */
8.1 --- a/xen/include/public/sysctl.h Mon Feb 08 08:43:25 2010 +0000 8.2 +++ b/xen/include/public/sysctl.h Mon Feb 08 08:48:40 2010 +0000 8.3 @@ -298,6 +298,7 @@ struct xen_ondemand { 8.4 8.5 uint32_t sampling_rate; 8.6 uint32_t up_threshold; 8.7 + uint32_t turbo_enabled; 8.8 }; 8.9 typedef struct xen_ondemand xen_ondemand_t; 8.10 8.11 @@ -390,6 +391,10 @@ struct xen_sysctl_pm_op { 8.12 #define XEN_SYSCTL_pm_op_set_vcpu_migration_delay 0x24 8.13 #define XEN_SYSCTL_pm_op_get_vcpu_migration_delay 0x25 8.14 8.15 + /* enable/disable turbo mode when in dbs governor */ 8.16 + #define XEN_SYSCTL_pm_op_enable_turbo 0x26 8.17 + #define XEN_SYSCTL_pm_op_disable_turbo 0x27 8.18 + 8.19 uint32_t cmd; 8.20 uint32_t cpuid; 8.21 union {