debuggers.hg

changeset 20954:a06e9def02bb

xenpm: Allow user to enable/disable dbs governor turbo mode.

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 {