debuggers.hg

changeset 21169:6c3db6c83a02

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>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Apr 09 08:52:43 2010 +0100 (2010-04-09)
parents f12db0ad5f45
children b432d7d9be92
files tools/libxc/xc_pm.c tools/libxc/xenctrl.h tools/misc/xenpm.c xen/arch/x86/acpi/cpufreq/cpufreq.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/acpi/cpufreq/processor_perf.h xen/include/public/sysctl.h
line diff
     1.1 --- a/tools/libxc/xc_pm.c	Thu Apr 08 16:11:17 2010 +0100
     1.2 +++ b/tools/libxc/xc_pm.c	Fri Apr 09 08:52:43 2010 +0100
     1.3 @@ -247,6 +247,7 @@ int xc_get_cpufreq_para(int xc_handle, i
     1.4          user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
     1.5          user_para->scaling_max_freq = sys_para->scaling_max_freq;
     1.6          user_para->scaling_min_freq = sys_para->scaling_min_freq;
     1.7 +        user_para->turbo_enabled    = sys_para->turbo_enabled;
     1.8  
     1.9          memcpy(user_para->scaling_driver, 
    1.10                  sys_para->scaling_driver, CPUFREQ_NAME_LEN);
     2.1 --- a/tools/libxc/xenctrl.h	Thu Apr 08 16:11:17 2010 +0100
     2.2 +++ b/tools/libxc/xenctrl.h	Fri Apr 09 08:52:43 2010 +0100
     2.3 @@ -1292,6 +1292,8 @@ struct xc_get_cpufreq_para {
     2.4          xc_userspace_t userspace;
     2.5          xc_ondemand_t ondemand;
     2.6      } u;
     2.7 +
     2.8 +    int32_t turbo_enabled;
     2.9  };
    2.10  
    2.11  int xc_get_cpufreq_para(int xc_handle, int cpuid,
     3.1 --- a/tools/misc/xenpm.c	Thu Apr 08 16:11:17 2010 +0100
     3.2 +++ b/tools/misc/xenpm.c	Fri Apr 09 08:52:43 2010 +0100
     3.3 @@ -30,6 +30,10 @@
     3.4  
     3.5  #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
     3.6  
     3.7 +#define CPUFREQ_TURBO_DISABLED      -1
     3.8 +#define CPUFREQ_TURBO_UNSUPPORTED   0
     3.9 +#define CPUFREQ_TURBO_ENABLED       1
    3.10 +
    3.11  static int xc_fd;
    3.12  static int max_cpu_nr;
    3.13  
    3.14 @@ -62,8 +66,8 @@ void show_help(void)
    3.15              " set-max-cstate        <num>         set the C-State limitation (<num> >= 0)\n"
    3.16              " start [seconds]                     start collect Cx/Px statistics,\n"
    3.17              "                                     output after CTRL-C or SIGINT or several seconds.\n"
    3.18 -            " enable-turbo-mode     [cpuid]       enable Turbo Mode in DBS governor.\n"
    3.19 -            " disable-turbo-mode    [cpuid]       disable Turbo Mode in DBS governor.\n"
    3.20 +            " enable-turbo-mode     [cpuid]       enable Turbo Mode for processors that support it.\n"
    3.21 +            " disable-turbo-mode    [cpuid]       disable Turbo Mode for processors that support it.\n"
    3.22              );
    3.23  }
    3.24  /* wrapper function */
    3.25 @@ -529,8 +533,6 @@ static void print_cpufreq_para(int cpuid
    3.26                 p_cpufreq->u.ondemand.sampling_rate);
    3.27          printf("    up_threshold     : %u\n",
    3.28                 p_cpufreq->u.ondemand.up_threshold);
    3.29 -        printf("    turbo mode       : %s\n",
    3.30 -               p_cpufreq->u.ondemand.turbo_enabled ? "enabled" : "disabled");
    3.31      }
    3.32  
    3.33      printf("scaling_avail_freq   :");
    3.34 @@ -546,6 +548,13 @@ static void print_cpufreq_para(int cpuid
    3.35             p_cpufreq->scaling_max_freq,
    3.36             p_cpufreq->scaling_min_freq,
    3.37             p_cpufreq->scaling_cur_freq);
    3.38 +    if (p_cpufreq->turbo_enabled != CPUFREQ_TURBO_UNSUPPORTED) {
    3.39 +           printf("turbo mode           : ");
    3.40 +           if (p_cpufreq->turbo_enabled == CPUFREQ_TURBO_ENABLED)
    3.41 +               printf("enabled\n");
    3.42 +           else
    3.43 +               printf("disabled\n");
    3.44 +    }
    3.45      printf("\n");
    3.46  }
    3.47  
    3.48 @@ -561,6 +570,7 @@ static int show_cpufreq_para_by_cpuid(in
    3.49      p_cpufreq->affected_cpus = NULL;
    3.50      p_cpufreq->scaling_available_frequencies = NULL;
    3.51      p_cpufreq->scaling_available_governors = NULL;
    3.52 +    p_cpufreq->turbo_enabled = 0;
    3.53  
    3.54      do
    3.55      {
     4.1 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c	Thu Apr 08 16:11:17 2010 +0100
     4.2 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c	Fri Apr 09 08:52:43 2010 +0100
     4.3 @@ -410,6 +410,10 @@ static int acpi_cpufreq_target(struct cp
     4.4          return -ENODEV;
     4.5      }
     4.6  
     4.7 +    if (policy->turbo == CPUFREQ_TURBO_DISABLED)
     4.8 +        if (target_freq > policy->cpuinfo.second_max_freq)
     4.9 +            target_freq = policy->cpuinfo.second_max_freq;
    4.10 +
    4.11      perf = data->acpi_data;
    4.12      result = cpufreq_frequency_table_target(policy,
    4.13                                              data->freq_table,
    4.14 @@ -610,12 +614,19 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol
    4.15          break;
    4.16      }
    4.17  
    4.18 -    /* Check for APERF/MPERF support in hardware */
    4.19 +    /* Check for APERF/MPERF support in hardware
    4.20 +     * also check for boost support */
    4.21      if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
    4.22          unsigned int ecx;
    4.23 +        unsigned int eax;
    4.24          ecx = cpuid_ecx(6);
    4.25          if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
    4.26              acpi_cpufreq_driver.getavg = get_measured_perf;
    4.27 +        eax = cpuid_eax(6);
    4.28 +        if ( eax & 0x2 ) {
    4.29 +            policy->turbo = CPUFREQ_TURBO_ENABLED;
    4.30 +            printk(XENLOG_INFO "Turbo Mode detected and enabled!\n");
    4.31 +        }
    4.32      }
    4.33  
    4.34      /*
     5.1 --- a/xen/drivers/acpi/pmstat.c	Thu Apr 08 16:11:17 2010 +0100
     5.2 +++ b/xen/drivers/acpi/pmstat.c	Fri Apr 09 08:52:43 2010 +0100
     5.3 @@ -299,9 +299,8 @@ static int get_cpufreq_para(struct xen_s
     5.4              &op->u.get_para.u.ondemand.sampling_rate_min,
     5.5              &op->u.get_para.u.ondemand.sampling_rate,
     5.6              &op->u.get_para.u.ondemand.up_threshold);
     5.7 -        op->u.get_para.u.ondemand.turbo_enabled =
     5.8 -            cpufreq_dbs_get_turbo_status(op->cpuid);
     5.9      }
    5.10 +    op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
    5.11  
    5.12      return ret;
    5.13  }
    5.14 @@ -553,13 +552,13 @@ int do_pm_op(struct xen_sysctl_pm_op *op
    5.15  
    5.16      case XEN_SYSCTL_pm_op_enable_turbo:
    5.17      {
    5.18 -        cpufreq_dbs_enable_turbo(op->cpuid);
    5.19 +        cpufreq_enable_turbo(op->cpuid);
    5.20          break;
    5.21      }
    5.22  
    5.23      case XEN_SYSCTL_pm_op_disable_turbo:
    5.24      {
    5.25 -        cpufreq_dbs_disable_turbo(op->cpuid);
    5.26 +        cpufreq_disable_turbo(op->cpuid);
    5.27          break;
    5.28      }
    5.29  
     6.1 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c	Thu Apr 08 16:11:17 2010 +0100
     6.2 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c	Fri Apr 09 08:52:43 2010 +0100
     6.3 @@ -58,9 +58,6 @@ static struct dbs_tuners {
     6.4  
     6.5  static struct timer dbs_timer[NR_CPUS];
     6.6  
     6.7 -/* Turbo Mode */
     6.8 -static int turbo_detected = 0;
     6.9 -
    6.10  int write_ondemand_sampling_rate(unsigned int sampling_rate)
    6.11  {
    6.12      if ( (sampling_rate > MAX_SAMPLING_RATE / MICROSECS(1)) ||
    6.13 @@ -111,10 +108,6 @@ static void dbs_check_cpu(struct cpu_dbs
    6.14  
    6.15      policy = this_dbs_info->cur_policy;
    6.16      max = policy->max;
    6.17 -    if (turbo_detected && !this_dbs_info->turbo_enabled) {
    6.18 -        if (max > policy->cpuinfo.second_max_freq)
    6.19 -            max = policy->cpuinfo.second_max_freq;
    6.20 -    }
    6.21  
    6.22      if (unlikely(policy->resume)) {
    6.23          __cpufreq_driver_target(policy, max,CPUFREQ_RELATION_H);
    6.24 @@ -276,7 +269,6 @@ int cpufreq_governor_dbs(struct cpufreq_
    6.25              } else
    6.26                  dbs_tuners_ins.sampling_rate = usr_sampling_rate;
    6.27          }
    6.28 -        this_dbs_info->turbo_enabled = 1;
    6.29          dbs_timer_init(this_dbs_info);
    6.30  
    6.31          break;
    6.32 @@ -353,13 +345,6 @@ struct cpufreq_governor cpufreq_gov_dbs 
    6.33  
    6.34  static int __init cpufreq_gov_dbs_init(void)
    6.35  {
    6.36 -#ifdef CONFIG_X86
    6.37 -    unsigned int eax = cpuid_eax(6);
    6.38 -    if ( eax & 0x2 ) {
    6.39 -        turbo_detected = 1;
    6.40 -        printk(XENLOG_INFO "Turbo Mode detected!\n");
    6.41 -    }
    6.42 -#endif
    6.43      return cpufreq_register_governor(&cpufreq_gov_dbs);
    6.44  }
    6.45  __initcall(cpufreq_gov_dbs_init);
    6.46 @@ -404,19 +389,3 @@ void cpufreq_dbs_timer_resume(void)
    6.47          }
    6.48      }
    6.49  }
    6.50 -
    6.51 -void cpufreq_dbs_enable_turbo(int cpuid)
    6.52 -{
    6.53 -    per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 1;
    6.54 -}
    6.55 -
    6.56 -void cpufreq_dbs_disable_turbo(int cpuid)
    6.57 -{
    6.58 -    per_cpu(cpu_dbs_info, cpuid).turbo_enabled = 0;
    6.59 -}
    6.60 -
    6.61 -unsigned int cpufreq_dbs_get_turbo_status(int cpuid)
    6.62 -{
    6.63 -    return turbo_detected && per_cpu(cpu_dbs_info, cpuid).turbo_enabled;
    6.64 -}
    6.65 -
     7.1 --- a/xen/drivers/cpufreq/utility.c	Thu Apr 08 16:11:17 2010 +0100
     7.2 +++ b/xen/drivers/cpufreq/utility.c	Fri Apr 09 08:52:43 2010 +0100
     7.3 @@ -394,6 +394,31 @@ int cpufreq_driver_getavg(unsigned int c
     7.4      return policy->cur;
     7.5  }
     7.6  
     7.7 +void cpufreq_enable_turbo(int cpuid)
     7.8 +{
     7.9 +    struct cpufreq_policy *policy;
    7.10 +
    7.11 +    policy = cpufreq_cpu_policy[cpuid];
    7.12 +    if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
    7.13 +        policy->turbo = CPUFREQ_TURBO_ENABLED;
    7.14 +}
    7.15 +
    7.16 +void cpufreq_disable_turbo(int cpuid)
    7.17 +{
    7.18 +    struct cpufreq_policy *policy;
    7.19 +
    7.20 +    policy = cpufreq_cpu_policy[cpuid];
    7.21 +    if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED)
    7.22 +        policy->turbo = CPUFREQ_TURBO_DISABLED;
    7.23 +}
    7.24 +
    7.25 +int cpufreq_get_turbo_status(int cpuid)
    7.26 +{
    7.27 +    struct cpufreq_policy *policy;
    7.28 +
    7.29 +    policy = cpufreq_cpu_policy[cpuid];
    7.30 +    return policy->turbo;
    7.31 +}
    7.32  
    7.33  /*********************************************************************
    7.34   *                 POLICY                                            *
     8.1 --- a/xen/include/acpi/cpufreq/cpufreq.h	Thu Apr 08 16:11:17 2010 +0100
     8.2 +++ b/xen/include/acpi/cpufreq/cpufreq.h	Fri Apr 09 08:52:43 2010 +0100
     8.3 @@ -55,6 +55,9 @@ struct cpufreq_policy {
     8.4  
     8.5      unsigned int        resume; /* flag for cpufreq 1st run
     8.6                                   * S3 wakeup, hotplug cpu, etc */
     8.7 +    int                 turbo;  /* tristate flag: 0 for unsupported
     8.8 +                                 * -1 for disable, 1 for enabled
     8.9 +                                 * See CPUFREQ_TURBO_* below for defines */
    8.10  };
    8.11  extern struct cpufreq_policy *cpufreq_cpu_policy[NR_CPUS];
    8.12  
    8.13 @@ -114,6 +117,14 @@ extern int __cpufreq_driver_target(struc
    8.14  #define USR_GETAVG     2
    8.15  extern int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag);
    8.16  
    8.17 +#define CPUFREQ_TURBO_DISABLED      -1
    8.18 +#define CPUFREQ_TURBO_UNSUPPORTED   0
    8.19 +#define CPUFREQ_TURBO_ENABLED       1
    8.20 +
    8.21 +extern void cpufreq_enable_turbo(int cpuid);
    8.22 +extern void cpufreq_disable_turbo(int cpuid);
    8.23 +extern int cpufreq_get_turbo_status(int cpuid);
    8.24 +
    8.25  static __inline__ int 
    8.26  __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
    8.27  {
    8.28 @@ -241,7 +252,4 @@ int write_userspace_scaling_setspeed(uns
    8.29  void cpufreq_dbs_timer_suspend(void);
    8.30  void cpufreq_dbs_timer_resume(void);
    8.31  
    8.32 -void cpufreq_dbs_enable_turbo(int cpuid);
    8.33 -void cpufreq_dbs_disable_turbo(int cpuid);
    8.34 -unsigned int cpufreq_dbs_get_turbo_status(int cpuid);
    8.35  #endif /* __XEN_CPUFREQ_PM_H__ */
     9.1 --- a/xen/include/acpi/cpufreq/processor_perf.h	Thu Apr 08 16:11:17 2010 +0100
     9.2 +++ b/xen/include/acpi/cpufreq/processor_perf.h	Fri Apr 09 08:52:43 2010 +0100
     9.3 @@ -9,7 +9,6 @@
     9.4  int get_cpu_id(u8);
     9.5  int powernow_cpufreq_init(void);
     9.6  unsigned int powernow_register_driver(void);
     9.7 -
     9.8  void cpufreq_residency_update(unsigned int, uint8_t);
     9.9  void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t);
    9.10  int  cpufreq_statistic_init(unsigned int);
    10.1 --- a/xen/include/public/sysctl.h	Thu Apr 08 16:11:17 2010 +0100
    10.2 +++ b/xen/include/public/sysctl.h	Fri Apr 09 08:52:43 2010 +0100
    10.3 @@ -283,7 +283,6 @@ struct xen_ondemand {
    10.4  
    10.5      uint32_t sampling_rate;
    10.6      uint32_t up_threshold;
    10.7 -    uint32_t turbo_enabled;
    10.8  };
    10.9  typedef struct xen_ondemand xen_ondemand_t;
   10.10  
   10.11 @@ -319,6 +318,8 @@ struct xen_get_cpufreq_para {
   10.12          struct  xen_userspace userspace;
   10.13          struct  xen_ondemand ondemand;
   10.14      } u;
   10.15 +
   10.16 +    int32_t turbo_enabled;
   10.17  };
   10.18  
   10.19  struct xen_set_cpufreq_gov {