All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor
@ 2014-10-07 14:19 Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
                   ` (13 more replies)
  0 siblings, 14 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Hi to all.

Next series of patches implements xen-cpufreq driver in Xen hypervisor.

Cpufreq core and registered cpufreq governors are located in xen. Dom0 has CPU
driver which can only change frequency of the physical CPUs. In addition this
driver can change CPUs regulator voltage. At start time xen-cpufreq driver
in kernel uploads to Xen information about physical cpus.
Xen notifies Dom0 kernel using VIRQ_CPUFREQ interrupt. Then xen-cpufreq driver
in kernel uses XEN_SYSCTL_cpufreq_op operation from HYPERVISOR_sysctl hypercall
to get some parameters from Xen (frequency, relation and cpu number).
Then xen-cpufreq changes frequency on physical cpu and uses the same
XEN_SYSCTL_cpufreq_op operation ti give the result to Xen.

Oleksandr Dmytryshyn (13):
  cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  pm: move processor_perf.h file to the xen/include/cpufreq location
  pmstat: move pmstat.c file to the xen/drivers/pm location
  cpufreq: use turbo settings only for x86 architecture
  pmstat: make pmstat functions more generalizable
  cpufreq: make cpufreq driver more generalizable
  xen/arm: enable cpu hotplug
  xen/dts: make the dt_find_property function to be global
  arch/arm: create device tree nodes for Dom0 cpufreq cpu driver
  xen: arm: implement platform hypercall
  cpufreq: add xen-cpufreq driver
  xen: arm: implement XEN_SYSCTL_cpufreq_op
  xen/arm: enable cpufreq functionality for ARM

 xen/Rules.mk                                 |   3 +
 xen/arch/arm/Makefile                        |   1 +
 xen/arch/arm/Rules.mk                        |   3 +
 xen/arch/arm/domain_build.c                  |  58 +++
 xen/arch/arm/platform_hypercall.c            |  98 +++++
 xen/arch/arm/traps.c                         |   1 +
 xen/arch/x86/Rules.mk                        |   1 +
 xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
 xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
 xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
 xen/arch/x86/acpi/power.c                    |   2 +-
 xen/arch/x86/cpu/mwait-idle.c                |   2 +-
 xen/arch/x86/platform_hypercall.c            |   2 +-
 xen/common/device_tree.c                     |   2 +-
 xen/common/sysctl.c                          |  10 +-
 xen/drivers/Makefile                         |   1 +
 xen/drivers/acpi/Makefile                    |   1 -
 xen/drivers/acpi/pmstat.c                    | 528 --------------------------
 xen/drivers/cpufreq/Makefile                 |   1 +
 xen/drivers/cpufreq/cpufreq.c                |  48 ++-
 xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
 xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
 xen/drivers/cpufreq/utility.c                |  13 +-
 xen/drivers/cpufreq/xen-cpufreq.c            | 267 +++++++++++++
 xen/drivers/pm/Makefile                      |   1 +
 xen/drivers/pm/pmstat.c                      | 539 +++++++++++++++++++++++++++
 xen/include/acpi/cpufreq/cpufreq.h           | 258 -------------
 xen/include/acpi/cpufreq/processor_perf.h    |  63 ----
 xen/include/asm-arm/config.h                 |   3 +
 xen/include/cpufreq/cpufreq.h                | 272 ++++++++++++++
 xen/include/cpufreq/processor_perf.h         |  70 ++++
 xen/include/public/sysctl.h                  |  19 +
 xen/include/public/xen.h                     |   1 +
 xen/include/xen/device_tree.h                |   9 +
 34 files changed, 1420 insertions(+), 869 deletions(-)
 create mode 100644 xen/arch/arm/platform_hypercall.c
 delete mode 100644 xen/drivers/acpi/pmstat.c
 create mode 100644 xen/drivers/cpufreq/xen-cpufreq.c
 create mode 100644 xen/drivers/pm/Makefile
 create mode 100644 xen/drivers/pm/pmstat.c
 delete mode 100644 xen/include/acpi/cpufreq/cpufreq.h
 delete mode 100644 xen/include/acpi/cpufreq/processor_perf.h
 create mode 100644 xen/include/cpufreq/cpufreq.h
 create mode 100644 xen/include/cpufreq/processor_perf.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:22   ` Andrew Cooper
  2014-10-07 14:35   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 02/13] pm: move processor_perf.h " Oleksandr Dmytryshyn
                   ` (12 subsequent siblings)
  13 siblings, 2 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Cpufreq driver should be more generalizable (not ACPI-specific).
Thus this file should be placed to the proper location.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
 xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
 xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
 xen/arch/x86/acpi/power.c                    |   2 +-
 xen/arch/x86/cpu/mwait-idle.c                |   2 +-
 xen/drivers/acpi/pmstat.c                    |   2 +-
 xen/drivers/cpufreq/cpufreq.c                |   2 +-
 xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
 xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
 xen/drivers/cpufreq/utility.c                |   2 +-
 xen/include/acpi/cpufreq/cpufreq.h           | 258 --------------------------
 xen/include/cpufreq/cpufreq.h                | 261 +++++++++++++++++++++++++++
 12 files changed, 272 insertions(+), 269 deletions(-)
 delete mode 100644 xen/include/acpi/cpufreq/cpufreq.h
 create mode 100644 xen/include/cpufreq/cpufreq.h

diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index 597befa..98726ad 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -51,7 +51,7 @@
 #include <xen/softirq.h>
 #include <public/platform.h>
 #include <public/sysctl.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 #include <asm/apic.h>
 #include <asm/cpuidle.h>
 #include <asm/mwait.h>
diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c
index 4a6aeb3..4569d49 100644
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
@@ -42,7 +42,7 @@
 #include <asm/percpu.h>
 #include <asm/cpufeature.h>
 #include <acpi/acpi.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 enum {
     UNDEFINED_CAPABLE = 0,
diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c
index 2c9fea2..0462e31 100644
--- a/xen/arch/x86/acpi/cpufreq/powernow.c
+++ b/xen/arch/x86/acpi/cpufreq/powernow.c
@@ -36,7 +36,7 @@
 #include <asm/percpu.h>
 #include <asm/cpufeature.h>
 #include <acpi/acpi.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 #define CPUID_6_ECX_APERFMPERF_CAPABILITY       (0x1)
 #define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index f41f0de..d139e96 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -29,7 +29,7 @@
 #include <asm/tboot.h>
 #include <asm/apic.h>
 #include <asm/io_apic.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 uint32_t system_reset_counter = 1;
 
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
index 85179f2..a00c19a 100644
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -59,7 +59,7 @@
 #include <asm/hpet.h>
 #include <asm/mwait.h>
 #include <asm/msr.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 #define MWAIT_IDLE_VERSION "0.4"
 #undef PREFIX
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
index daac2da..bd6ca43 100644
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -40,7 +40,7 @@
 #include <xen/acpi.h>
 
 #include <public/sysctl.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 #include <xen/pmstat.h>
 
 DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index ab66884..884d2bb 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -44,7 +44,7 @@
 #include <asm/processor.h>
 #include <asm/percpu.h>
 #include <acpi/acpi.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 static unsigned int __read_mostly usr_min_freq;
 static unsigned int __read_mostly usr_max_freq;
diff --git a/xen/drivers/cpufreq/cpufreq_misc_governors.c b/xen/drivers/cpufreq/cpufreq_misc_governors.c
index 746bbcd..881e4bb 100644
--- a/xen/drivers/cpufreq/cpufreq_misc_governors.c
+++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c
@@ -18,7 +18,7 @@
 #include <xen/init.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 /*
  * cpufreq userspace governor
diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
index 7fdba03..f299116 100644
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
@@ -1,5 +1,5 @@
 /*
- *  xen/arch/x86/acpi/cpufreq/cpufreq_ondemand.c
+ *  xen/drivers/cpufreq/cpufreq_ondemand.c
  *
  *  Copyright (C)  2001 Russell King
  *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
@@ -18,7 +18,7 @@
 #include <xen/types.h>
 #include <xen/sched.h>
 #include <xen/timer.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 
 #define DEF_FREQUENCY_UP_THRESHOLD              (80)
 #define MIN_FREQUENCY_UP_THRESHOLD              (11)
diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c
index 519f862..c9150a1 100644
--- a/xen/drivers/cpufreq/utility.c
+++ b/xen/drivers/cpufreq/utility.c
@@ -28,7 +28,7 @@
 #include <xen/sched.h>
 #include <xen/timer.h>
 #include <xen/trace.h>
-#include <acpi/cpufreq/cpufreq.h>
+#include <cpufreq/cpufreq.h>
 #include <public/sysctl.h>
 
 struct cpufreq_driver   *cpufreq_driver;
diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h
deleted file mode 100644
index f96c3e4..0000000
--- a/xen/include/acpi/cpufreq/cpufreq.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *  xen/include/acpi/cpufreq/cpufreq.h
- *
- *  Copyright (C) 2001 Russell King
- *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
- *
- * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __XEN_CPUFREQ_PM_H__
-#define __XEN_CPUFREQ_PM_H__
-
-#include <xen/types.h>
-#include <xen/list.h>
-#include <xen/cpumask.h>
-
-#include "processor_perf.h"
-
-DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
-
-extern bool_t cpufreq_verbose;
-
-struct cpufreq_governor;
-
-struct acpi_cpufreq_data {
-    struct processor_performance *acpi_data;
-    struct cpufreq_frequency_table *freq_table;
-    unsigned int arch_cpu_flags;
-};
-
-extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
-
-struct cpufreq_cpuinfo {
-    unsigned int        max_freq;
-    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
-    unsigned int        min_freq;
-    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
-};
-
-struct cpufreq_policy {
-    cpumask_var_t       cpus;          /* affected CPUs */
-    unsigned int        shared_type;   /* ANY or ALL affected CPUs
-                                          should set cpufreq */
-    unsigned int        cpu;           /* cpu nr of registered CPU */
-    struct cpufreq_cpuinfo    cpuinfo;
-
-    unsigned int        min;    /* in kHz */
-    unsigned int        max;    /* in kHz */
-    unsigned int        cur;    /* in kHz, only needed if cpufreq
-                                 * governors are used */
-    struct cpufreq_governor     *governor;
-
-    bool_t              resume; /* flag for cpufreq 1st run
-                                 * S3 wakeup, hotplug cpu, etc */
-    s8                  turbo;  /* tristate flag: 0 for unsupported
-                                 * -1 for disable, 1 for enabled
-                                 * See CPUFREQ_TURBO_* below for defines */
-    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
-};
-DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
-
-extern int __cpufreq_set_policy(struct cpufreq_policy *data,
-                                struct cpufreq_policy *policy);
-
-void cpufreq_cmdline_parse(char *);
-
-#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
-#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
-#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
-#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
-
-/******************** cpufreq transition notifiers *******************/
-
-struct cpufreq_freqs {
-    unsigned int cpu;    /* cpu nr */
-    unsigned int old;
-    unsigned int new;
-    u8 flags;            /* flags of cpufreq_driver, see below. */
-};
-
-
-/*********************************************************************
- *                          CPUFREQ GOVERNORS                        *
- *********************************************************************/
-
-#define CPUFREQ_GOV_START  1
-#define CPUFREQ_GOV_STOP   2
-#define CPUFREQ_GOV_LIMITS 3
-
-struct cpufreq_governor {
-    char    name[CPUFREQ_NAME_LEN];
-    int     (*governor)(struct cpufreq_policy *policy,
-                        unsigned int event);
-    bool_t  (*handle_option)(const char *name, const char *value);
-    struct list_head governor_list;
-};
-
-extern struct cpufreq_governor *cpufreq_opt_governor;
-extern struct cpufreq_governor cpufreq_gov_dbs;
-extern struct cpufreq_governor cpufreq_gov_userspace;
-extern struct cpufreq_governor cpufreq_gov_performance;
-extern struct cpufreq_governor cpufreq_gov_powersave;
-
-extern struct list_head cpufreq_governor_list;
-
-extern int cpufreq_register_governor(struct cpufreq_governor *governor);
-extern struct cpufreq_governor *__find_governor(const char *governor);
-#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
-
-/* pass a target to the cpufreq driver */
-extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
-                                   unsigned int target_freq,
-                                   unsigned int relation);
-
-#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 int cpufreq_update_turbo(int cpuid, int new_state);
-extern int cpufreq_get_turbo_status(int cpuid);
-
-static __inline__ int 
-__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
-{
-    return policy->governor->governor(policy, event);
-}
-
-
-/*********************************************************************
- *                      CPUFREQ DRIVER INTERFACE                     *
- *********************************************************************/
-
-#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
-#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
-
-struct cpufreq_driver {
-    char   name[CPUFREQ_NAME_LEN];
-    int    (*init)(struct cpufreq_policy *policy);
-    int    (*verify)(struct cpufreq_policy *policy);
-    int    (*update)(int cpuid, struct cpufreq_policy *policy);
-    int    (*target)(struct cpufreq_policy *policy,
-                     unsigned int target_freq,
-                     unsigned int relation);
-    unsigned int    (*get)(unsigned int cpu);
-    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
-    int    (*exit)(struct cpufreq_policy *policy);
-};
-
-extern struct cpufreq_driver *cpufreq_driver;
-
-static __inline__ 
-int cpufreq_register_driver(struct cpufreq_driver *driver_data)
-{
-    if (!driver_data         || 
-        !driver_data->init   || 
-        !driver_data->exit   || 
-        !driver_data->verify || 
-        !driver_data->target)
-        return -EINVAL;
-
-    if (cpufreq_driver)
-        return -EBUSY;
-
-    cpufreq_driver = driver_data;
-    return 0;
-}
-
-static __inline__ 
-int cpufreq_unregister_driver(struct cpufreq_driver *driver)
-{
-    if (!cpufreq_driver || (driver != cpufreq_driver))
-        return -EINVAL;
-
-    cpufreq_driver = NULL;
-    return 0;
-}
-
-static __inline__
-void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
-                                  unsigned int min, unsigned int max)
-{
-    if (policy->min < min)
-        policy->min = min;
-    if (policy->max < min)
-        policy->max = min;
-    if (policy->min > max)
-        policy->min = max;
-    if (policy->max > max)
-        policy->max = max;
-    if (policy->min > policy->max)
-        policy->min = policy->max;
-    return;
-}
-
-
-/*********************************************************************
- *                     FREQUENCY TABLE HELPERS                       *
- *********************************************************************/
-
-#define CPUFREQ_ENTRY_INVALID ~0
-#define CPUFREQ_TABLE_END     ~1
-
-struct cpufreq_frequency_table {
-    unsigned int    index;     /* any */
-    unsigned int    frequency; /* kHz - doesn't need to be in ascending
-                                * order */
-};
-
-int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
-                   struct cpufreq_frequency_table *table);
-
-int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
-                   struct cpufreq_frequency_table *table);
-
-int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-                   struct cpufreq_frequency_table *table,
-                   unsigned int target_freq,
-                   unsigned int relation,
-                   unsigned int *index);
-
-
-/*********************************************************************
- *                     UNIFIED DEBUG HELPERS                         *
- *********************************************************************/
-
-struct cpu_dbs_info_s {
-    uint64_t prev_cpu_idle;
-    uint64_t prev_cpu_wall;
-    struct cpufreq_policy *cur_policy;
-    struct cpufreq_frequency_table *freq_table;
-    int cpu;
-    unsigned int enable:1;
-    unsigned int stoppable:1;
-    unsigned int turbo_enabled:1;
-};
-
-int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
-int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
-                              uint32_t *sampling_rate_min,
-                              uint32_t *sampling_rate,
-                              uint32_t *up_threshold);
-int write_ondemand_sampling_rate(unsigned int sampling_rate);
-int write_ondemand_up_threshold(unsigned int up_threshold);
-
-int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
-
-void cpufreq_dbs_timer_suspend(void);
-void cpufreq_dbs_timer_resume(void);
-
-#endif /* __XEN_CPUFREQ_PM_H__ */
diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
new file mode 100644
index 0000000..04716f9
--- /dev/null
+++ b/xen/include/cpufreq/cpufreq.h
@@ -0,0 +1,261 @@
+/*
+ *  xen/include/cpufreq/cpufreq.h
+ *
+ *  Copyright (C) 2001 Russell King
+ *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XEN_CPUFREQ_PM_H__
+#define __XEN_CPUFREQ_PM_H__
+
+#include <xen/types.h>
+#include <xen/list.h>
+#include <xen/percpu.h>
+#include <xen/spinlock.h>
+#include <xen/errno.h>
+#include <xen/cpumask.h>
+
+#include <acpi/cpufreq/processor_perf.h>
+
+DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
+
+extern bool_t cpufreq_verbose;
+
+struct cpufreq_governor;
+
+struct acpi_cpufreq_data {
+    struct processor_performance *acpi_data;
+    struct cpufreq_frequency_table *freq_table;
+    unsigned int arch_cpu_flags;
+};
+
+extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
+
+struct cpufreq_cpuinfo {
+    unsigned int        max_freq;
+    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
+    unsigned int        min_freq;
+    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
+};
+
+struct cpufreq_policy {
+    cpumask_var_t       cpus;          /* affected CPUs */
+    unsigned int        shared_type;   /* ANY or ALL affected CPUs
+                                          should set cpufreq */
+    unsigned int        cpu;           /* cpu nr of registered CPU */
+    struct cpufreq_cpuinfo    cpuinfo;
+
+    unsigned int        min;    /* in kHz */
+    unsigned int        max;    /* in kHz */
+    unsigned int        cur;    /* in kHz, only needed if cpufreq
+                                 * governors are used */
+    struct cpufreq_governor     *governor;
+
+    bool_t              resume; /* flag for cpufreq 1st run
+                                 * S3 wakeup, hotplug cpu, etc */
+    s8                  turbo;  /* tristate flag: 0 for unsupported
+                                 * -1 for disable, 1 for enabled
+                                 * See CPUFREQ_TURBO_* below for defines */
+    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
+};
+DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
+
+extern int __cpufreq_set_policy(struct cpufreq_policy *data,
+                                struct cpufreq_policy *policy);
+
+void cpufreq_cmdline_parse(char *);
+
+#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
+#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
+#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
+#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
+
+/******************** cpufreq transition notifiers *******************/
+
+struct cpufreq_freqs {
+    unsigned int cpu;    /* cpu nr */
+    unsigned int old;
+    unsigned int new;
+    u8 flags;            /* flags of cpufreq_driver, see below. */
+};
+
+
+/*********************************************************************
+ *                          CPUFREQ GOVERNORS                        *
+ *********************************************************************/
+
+#define CPUFREQ_GOV_START  1
+#define CPUFREQ_GOV_STOP   2
+#define CPUFREQ_GOV_LIMITS 3
+
+struct cpufreq_governor {
+    char    name[CPUFREQ_NAME_LEN];
+    int     (*governor)(struct cpufreq_policy *policy,
+                        unsigned int event);
+    bool_t  (*handle_option)(const char *name, const char *value);
+    struct list_head governor_list;
+};
+
+extern struct cpufreq_governor *cpufreq_opt_governor;
+extern struct cpufreq_governor cpufreq_gov_dbs;
+extern struct cpufreq_governor cpufreq_gov_userspace;
+extern struct cpufreq_governor cpufreq_gov_performance;
+extern struct cpufreq_governor cpufreq_gov_powersave;
+
+extern struct list_head cpufreq_governor_list;
+
+extern int cpufreq_register_governor(struct cpufreq_governor *governor);
+extern struct cpufreq_governor *__find_governor(const char *governor);
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
+
+/* pass a target to the cpufreq driver */
+extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
+                                   unsigned int target_freq,
+                                   unsigned int relation);
+
+#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 int cpufreq_update_turbo(int cpuid, int new_state);
+extern int cpufreq_get_turbo_status(int cpuid);
+
+static __inline__ int 
+__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
+{
+    return policy->governor->governor(policy, event);
+}
+
+
+/*********************************************************************
+ *                      CPUFREQ DRIVER INTERFACE                     *
+ *********************************************************************/
+
+#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
+#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
+
+struct cpufreq_driver {
+    char   name[CPUFREQ_NAME_LEN];
+    int    (*init)(struct cpufreq_policy *policy);
+    int    (*verify)(struct cpufreq_policy *policy);
+    int    (*update)(int cpuid, struct cpufreq_policy *policy);
+    int    (*target)(struct cpufreq_policy *policy,
+                     unsigned int target_freq,
+                     unsigned int relation);
+    unsigned int    (*get)(unsigned int cpu);
+    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
+    int    (*exit)(struct cpufreq_policy *policy);
+};
+
+extern struct cpufreq_driver *cpufreq_driver;
+
+static __inline__ 
+int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+{
+    if (!driver_data         || 
+        !driver_data->init   || 
+        !driver_data->exit   || 
+        !driver_data->verify || 
+        !driver_data->target)
+        return -EINVAL;
+
+    if (cpufreq_driver)
+        return -EBUSY;
+
+    cpufreq_driver = driver_data;
+    return 0;
+}
+
+static __inline__ 
+int cpufreq_unregister_driver(struct cpufreq_driver *driver)
+{
+    if (!cpufreq_driver || (driver != cpufreq_driver))
+        return -EINVAL;
+
+    cpufreq_driver = NULL;
+    return 0;
+}
+
+static __inline__
+void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
+                                  unsigned int min, unsigned int max)
+{
+    if (policy->min < min)
+        policy->min = min;
+    if (policy->max < min)
+        policy->max = min;
+    if (policy->min > max)
+        policy->min = max;
+    if (policy->max > max)
+        policy->max = max;
+    if (policy->min > policy->max)
+        policy->min = policy->max;
+    return;
+}
+
+
+/*********************************************************************
+ *                     FREQUENCY TABLE HELPERS                       *
+ *********************************************************************/
+
+#define CPUFREQ_ENTRY_INVALID ~0
+#define CPUFREQ_TABLE_END     ~1
+
+struct cpufreq_frequency_table {
+    unsigned int    index;     /* any */
+    unsigned int    frequency; /* kHz - doesn't need to be in ascending
+                                * order */
+};
+
+int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+                   struct cpufreq_frequency_table *table);
+
+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+                   struct cpufreq_frequency_table *table);
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+                   struct cpufreq_frequency_table *table,
+                   unsigned int target_freq,
+                   unsigned int relation,
+                   unsigned int *index);
+
+
+/*********************************************************************
+ *                     UNIFIED DEBUG HELPERS                         *
+ *********************************************************************/
+
+struct cpu_dbs_info_s {
+    uint64_t prev_cpu_idle;
+    uint64_t prev_cpu_wall;
+    struct cpufreq_policy *cur_policy;
+    struct cpufreq_frequency_table *freq_table;
+    int cpu;
+    unsigned int enable:1;
+    unsigned int stoppable:1;
+    unsigned int turbo_enabled:1;
+};
+
+int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
+int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
+                              uint32_t *sampling_rate_min,
+                              uint32_t *sampling_rate,
+                              uint32_t *up_threshold);
+int write_ondemand_sampling_rate(unsigned int sampling_rate);
+int write_ondemand_up_threshold(unsigned int up_threshold);
+
+int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
+
+void cpufreq_dbs_timer_suspend(void);
+void cpufreq_dbs_timer_resume(void);
+
+#endif /* __XEN_CPUFREQ_PM_H__ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 02/13] pm: move processor_perf.h file to the xen/include/cpufreq location
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location Oleksandr Dmytryshyn
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Cpufreq driver should be more generalizable (not ACPI-specific).
Thus this file should be placed to the proper location.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/arch/x86/platform_hypercall.c         |  2 +-
 xen/include/acpi/cpufreq/processor_perf.h | 63 -------------------------------
 xen/include/cpufreq/cpufreq.h             |  2 +-
 xen/include/cpufreq/processor_perf.h      | 63 +++++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 65 deletions(-)
 delete mode 100644 xen/include/acpi/cpufreq/processor_perf.h
 create mode 100644 xen/include/cpufreq/processor_perf.h

diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 2162811..addbc91 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -25,7 +25,7 @@
 #include <xen/irq.h>
 #include <asm/current.h>
 #include <public/platform.h>
-#include <acpi/cpufreq/processor_perf.h>
+#include <cpufreq/processor_perf.h>
 #include <asm/edd.h>
 #include <asm/mtrr.h>
 #include <asm/io_apic.h>
diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h
deleted file mode 100644
index d8a1ba6..0000000
--- a/xen/include/acpi/cpufreq/processor_perf.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __XEN_PROCESSOR_PM_H__
-#define __XEN_PROCESSOR_PM_H__
-
-#include <public/platform.h>
-#include <public/sysctl.h>
-#include <xen/acpi.h>
-
-#define XEN_PX_INIT 0x80000000
-
-int powernow_cpufreq_init(void);
-unsigned int powernow_register_driver(void);
-unsigned int get_measured_perf(unsigned int cpu, unsigned int flag);
-void cpufreq_residency_update(unsigned int, uint8_t);
-void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t);
-int  cpufreq_statistic_init(unsigned int);
-void cpufreq_statistic_exit(unsigned int);
-void cpufreq_statistic_reset(unsigned int);
-
-int  cpufreq_limit_change(unsigned int);
-
-int  cpufreq_add_cpu(unsigned int);
-int  cpufreq_del_cpu(unsigned int);
-
-struct processor_performance {
-    uint32_t state;
-    uint32_t platform_limit;
-    struct xen_pct_register control_register;
-    struct xen_pct_register status_register;
-    uint32_t state_count;
-    struct xen_processor_px *states;
-    struct xen_psd_package domain_info;
-    uint32_t shared_type;
-
-    uint32_t init;
-};
-
-struct processor_pminfo {
-    uint32_t acpi_id;
-    uint32_t id;
-    struct processor_performance    perf;
-};
-
-extern struct processor_pminfo *processor_pminfo[NR_CPUS];
-
-struct px_stat {
-    uint8_t total;        /* total Px states */
-    uint8_t usable;       /* usable Px states */
-    uint8_t last;         /* last Px state */
-    uint8_t cur;          /* current Px state */
-    uint64_t *trans_pt;   /* Px transition table */
-    pm_px_val_t *pt;
-};
-
-struct pm_px {
-    struct px_stat u;
-    uint64_t prev_state_wall;
-    uint64_t prev_idle_wall;
-};
-
-DECLARE_PER_CPU(struct pm_px *, cpufreq_statistic_data);
-
-int cpufreq_cpu_init(unsigned int cpuid);
-#endif /* __XEN_PROCESSOR_PM_H__ */
diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
index 04716f9..dde7259 100644
--- a/xen/include/cpufreq/cpufreq.h
+++ b/xen/include/cpufreq/cpufreq.h
@@ -21,7 +21,7 @@
 #include <xen/errno.h>
 #include <xen/cpumask.h>
 
-#include <acpi/cpufreq/processor_perf.h>
+#include <cpufreq/processor_perf.h>
 
 DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
 
diff --git a/xen/include/cpufreq/processor_perf.h b/xen/include/cpufreq/processor_perf.h
new file mode 100644
index 0000000..d8a1ba6
--- /dev/null
+++ b/xen/include/cpufreq/processor_perf.h
@@ -0,0 +1,63 @@
+#ifndef __XEN_PROCESSOR_PM_H__
+#define __XEN_PROCESSOR_PM_H__
+
+#include <public/platform.h>
+#include <public/sysctl.h>
+#include <xen/acpi.h>
+
+#define XEN_PX_INIT 0x80000000
+
+int powernow_cpufreq_init(void);
+unsigned int powernow_register_driver(void);
+unsigned int get_measured_perf(unsigned int cpu, unsigned int flag);
+void cpufreq_residency_update(unsigned int, uint8_t);
+void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t);
+int  cpufreq_statistic_init(unsigned int);
+void cpufreq_statistic_exit(unsigned int);
+void cpufreq_statistic_reset(unsigned int);
+
+int  cpufreq_limit_change(unsigned int);
+
+int  cpufreq_add_cpu(unsigned int);
+int  cpufreq_del_cpu(unsigned int);
+
+struct processor_performance {
+    uint32_t state;
+    uint32_t platform_limit;
+    struct xen_pct_register control_register;
+    struct xen_pct_register status_register;
+    uint32_t state_count;
+    struct xen_processor_px *states;
+    struct xen_psd_package domain_info;
+    uint32_t shared_type;
+
+    uint32_t init;
+};
+
+struct processor_pminfo {
+    uint32_t acpi_id;
+    uint32_t id;
+    struct processor_performance    perf;
+};
+
+extern struct processor_pminfo *processor_pminfo[NR_CPUS];
+
+struct px_stat {
+    uint8_t total;        /* total Px states */
+    uint8_t usable;       /* usable Px states */
+    uint8_t last;         /* last Px state */
+    uint8_t cur;          /* current Px state */
+    uint64_t *trans_pt;   /* Px transition table */
+    pm_px_val_t *pt;
+};
+
+struct pm_px {
+    struct px_stat u;
+    uint64_t prev_state_wall;
+    uint64_t prev_idle_wall;
+};
+
+DECLARE_PER_CPU(struct pm_px *, cpufreq_statistic_data);
+
+int cpufreq_cpu_init(unsigned int cpuid);
+#endif /* __XEN_PROCESSOR_PM_H__ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 02/13] pm: move processor_perf.h " Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:38   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture Oleksandr Dmytryshyn
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Cpufreq driver should be more generalizable (not ACPI-specific).
Thus this file should be placed to the proper location.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/Rules.mk              |   1 +
 xen/arch/x86/Rules.mk     |   1 +
 xen/common/sysctl.c       |   2 +-
 xen/drivers/Makefile      |   1 +
 xen/drivers/acpi/Makefile |   1 -
 xen/drivers/acpi/pmstat.c | 528 ----------------------------------------------
 xen/drivers/pm/Makefile   |   1 +
 xen/drivers/pm/pmstat.c   | 528 ++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 533 insertions(+), 530 deletions(-)
 delete mode 100644 xen/drivers/acpi/pmstat.c
 create mode 100644 xen/drivers/pm/Makefile
 create mode 100644 xen/drivers/pm/pmstat.c

diff --git a/xen/Rules.mk b/xen/Rules.mk
index 3a6cec5..b7caab6 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -55,6 +55,7 @@ CFLAGS-$(perfc)         += -DPERF_COUNTERS
 CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
 CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
 CFLAGS-$(HAS_ACPI)      += -DHAS_ACPI
+CFLAGS-$(HAS_PM)        += -DHAS_PM
 CFLAGS-$(HAS_GDBSX)     += -DHAS_GDBSX
 CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
 CFLAGS-$(HAS_DEVICE_TREE) += -DHAS_DEVICE_TREE
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index 576985e..9e9fbf1 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -3,6 +3,7 @@
 
 HAS_IOPORTS := y
 HAS_ACPI := y
+HAS_PM := y
 HAS_VGA  := y
 HAS_VIDEO  := y
 HAS_CPUFREQ := y
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 0cb6ee1..0dcf06a 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -170,7 +170,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         op->u.availheap.avail_bytes <<= PAGE_SHIFT;
         break;
 
-#ifdef HAS_ACPI
+#ifdef HAS_PM
     case XEN_SYSCTL_get_pmstat:
         ret = do_get_pm_info(&op->u.get_pmstat);
         break;
diff --git a/xen/drivers/Makefile b/xen/drivers/Makefile
index 9c70f20..ee4fd4d 100644
--- a/xen/drivers/Makefile
+++ b/xen/drivers/Makefile
@@ -4,3 +4,4 @@ subdir-$(HAS_PCI) += pci
 subdir-$(HAS_PASSTHROUGH) += passthrough
 subdir-$(HAS_ACPI) += acpi
 subdir-$(HAS_VIDEO) += video
+subdir-$(HAS_PM) += pm
diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
index bbb06a7..0505742 100644
--- a/xen/drivers/acpi/Makefile
+++ b/xen/drivers/acpi/Makefile
@@ -5,7 +5,6 @@ subdir-$(x86) += apei
 obj-bin-y += tables.init.o
 obj-y += numa.o
 obj-y += osl.o
-obj-y += pmstat.o
 
 obj-$(x86) += hwregs.o
 obj-$(x86) += reboot.o
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
deleted file mode 100644
index bd6ca43..0000000
--- a/xen/drivers/acpi/pmstat.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*****************************************************************************
-#  pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
-#
-#  Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of the GNU General Public License as published by the Free 
-# Software Foundation; either version 2 of the License, or (at your option) 
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT 
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59 
-# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
-*****************************************************************************/
-
-#include <xen/config.h>
-#include <xen/lib.h>
-#include <xen/errno.h>
-#include <xen/sched.h>
-#include <xen/event.h>
-#include <xen/irq.h>
-#include <xen/iocap.h>
-#include <xen/compat.h>
-#include <xen/guest_access.h>
-#include <asm/current.h>
-#include <public/xen.h>
-#include <xen/cpumask.h>
-#include <asm/processor.h>
-#include <xen/percpu.h>
-#include <xen/domain.h>
-#include <xen/acpi.h>
-
-#include <public/sysctl.h>
-#include <cpufreq/cpufreq.h>
-#include <xen/pmstat.h>
-
-DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
-
-/*
- * Get PM statistic info
- */
-int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
-{
-    int ret = 0;
-    const struct processor_pminfo *pmpt;
-
-    if ( !op || (op->cpuid >= nr_cpu_ids) || !cpu_online(op->cpuid) )
-        return -EINVAL;
-    pmpt = processor_pminfo[op->cpuid];
-
-    switch ( op->type & PMSTAT_CATEGORY_MASK )
-    {
-    case PMSTAT_CX:
-        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
-            return -ENODEV;
-        break;
-    case PMSTAT_PX:
-        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
-            return -ENODEV;
-        if ( !cpufreq_driver )
-            return -ENODEV;
-        if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
-            return -EINVAL;
-        break;
-    default:
-        return -ENODEV;
-    }
-
-    switch ( op->type )
-    {
-    case PMSTAT_get_max_px:
-    {
-        op->u.getpx.total = pmpt->perf.state_count;
-        break;
-    }
-
-    case PMSTAT_get_pxstat:
-    {
-        uint32_t ct;
-        struct pm_px *pxpt;
-        spinlock_t *cpufreq_statistic_lock = 
-                   &per_cpu(cpufreq_statistic_lock, op->cpuid);
-
-        spin_lock(cpufreq_statistic_lock);
-
-        pxpt = per_cpu(cpufreq_statistic_data, op->cpuid);
-        if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
-        {
-            spin_unlock(cpufreq_statistic_lock);
-            return -ENODATA;
-        }
-
-        pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit;
-
-        cpufreq_residency_update(op->cpuid, pxpt->u.cur);
-
-        ct = pmpt->perf.state_count;
-        if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
-        {
-            spin_unlock(cpufreq_statistic_lock);
-            ret = -EFAULT;
-            break;
-        }
-
-        if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
-        {
-            spin_unlock(cpufreq_statistic_lock);
-            ret = -EFAULT;
-            break;
-        }
-
-        op->u.getpx.total = pxpt->u.total;
-        op->u.getpx.usable = pxpt->u.usable;
-        op->u.getpx.last = pxpt->u.last;
-        op->u.getpx.cur = pxpt->u.cur;
-
-        spin_unlock(cpufreq_statistic_lock);
-
-        break;
-    }
-
-    case PMSTAT_reset_pxstat:
-    {
-        cpufreq_statistic_reset(op->cpuid);
-        break;
-    }
-
-    case PMSTAT_get_max_cx:
-    {
-        op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
-        ret = 0;
-        break;
-    }
-
-    case PMSTAT_get_cxstat:
-    {
-        ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx);
-        break;
-    }
-
-    case PMSTAT_reset_cxstat:
-    {
-        ret = pmstat_reset_cx_stat(op->cpuid);
-        break;
-    }
-
-    default:
-        printk("not defined sub-hypercall @ do_get_pm_info\n");
-        ret = -ENOSYS;
-        break;
-    }
-
-    return ret;
-}
-
-/*
- * 1. Get PM parameter
- * 2. Provide user PM control
- */
-static int read_scaling_available_governors(char *scaling_available_governors,
-                                            unsigned int size)
-{
-    unsigned int i = 0;
-    struct cpufreq_governor *t;
-
-    if ( !scaling_available_governors )
-        return -EINVAL;
-
-    list_for_each_entry(t, &cpufreq_governor_list, governor_list)
-    {
-        i += scnprintf(&scaling_available_governors[i],
-                       CPUFREQ_NAME_LEN, "%s ", t->name);
-        if ( i > size )
-            return -EINVAL;
-    }
-    scaling_available_governors[i-1] = '\0';
-
-    return 0;
-}
-
-static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
-{
-    uint32_t ret = 0;
-    const struct processor_pminfo *pmpt;
-    struct cpufreq_policy *policy;
-    uint32_t gov_num = 0;
-    uint32_t *affected_cpus;
-    uint32_t *scaling_available_frequencies;
-    char     *scaling_available_governors;
-    struct list_head *pos;
-    uint32_t cpu, i, j = 0;
-
-    pmpt = processor_pminfo[op->cpuid];
-    policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
-
-    if ( !pmpt || !pmpt->perf.states ||
-         !policy || !policy->governor )
-        return -EINVAL;
-
-    list_for_each(pos, &cpufreq_governor_list)
-        gov_num++;
-
-    if ( (op->u.get_para.cpu_num  != cpumask_weight(policy->cpus)) ||
-         (op->u.get_para.freq_num != pmpt->perf.state_count)    ||
-         (op->u.get_para.gov_num  != gov_num) )
-    {
-        op->u.get_para.cpu_num =  cpumask_weight(policy->cpus);
-        op->u.get_para.freq_num = pmpt->perf.state_count;
-        op->u.get_para.gov_num  = gov_num;
-        return -EAGAIN;
-    }
-
-    if ( !(affected_cpus = xzalloc_array(uint32_t, op->u.get_para.cpu_num)) )
-        return -ENOMEM;
-    for_each_cpu(cpu, policy->cpus)
-        affected_cpus[j++] = cpu;
-    ret = copy_to_guest(op->u.get_para.affected_cpus,
-                       affected_cpus, op->u.get_para.cpu_num);
-    xfree(affected_cpus);
-    if ( ret )
-        return ret;
-
-    if ( !(scaling_available_frequencies =
-           xzalloc_array(uint32_t, op->u.get_para.freq_num)) )
-        return -ENOMEM;
-    for ( i = 0; i < op->u.get_para.freq_num; i++ )
-        scaling_available_frequencies[i] =
-                        pmpt->perf.states[i].core_frequency * 1000;
-    ret = copy_to_guest(op->u.get_para.scaling_available_frequencies,
-                   scaling_available_frequencies, op->u.get_para.freq_num);
-    xfree(scaling_available_frequencies);
-    if ( ret )
-        return ret;
-
-    if ( !(scaling_available_governors =
-           xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
-        return -ENOMEM;
-    if ( (ret = read_scaling_available_governors(scaling_available_governors,
-                gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
-    {
-        xfree(scaling_available_governors);
-        return ret;
-    }
-    ret = copy_to_guest(op->u.get_para.scaling_available_governors,
-                scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
-    xfree(scaling_available_governors);
-    if ( ret )
-        return ret;
-
-    op->u.get_para.cpuinfo_cur_freq =
-        cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
-    op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
-    op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
-    op->u.get_para.scaling_cur_freq = policy->cur;
-    op->u.get_para.scaling_max_freq = policy->max;
-    op->u.get_para.scaling_min_freq = policy->min;
-
-    if ( cpufreq_driver->name[0] )
-        strlcpy(op->u.get_para.scaling_driver, 
-            cpufreq_driver->name, CPUFREQ_NAME_LEN);
-    else
-        strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
-
-    if ( policy->governor->name[0] )
-        strlcpy(op->u.get_para.scaling_governor, 
-            policy->governor->name, CPUFREQ_NAME_LEN);
-    else
-        strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
-
-    /* governor specific para */
-    if ( !strnicmp(op->u.get_para.scaling_governor, 
-                   "userspace", CPUFREQ_NAME_LEN) )
-    {
-        op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
-    }
-
-    if ( !strnicmp(op->u.get_para.scaling_governor, 
-                   "ondemand", CPUFREQ_NAME_LEN) )
-    {
-        ret = get_cpufreq_ondemand_para(
-            &op->u.get_para.u.ondemand.sampling_rate_max,
-            &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.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
-
-    return ret;
-}
-
-static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
-{
-    struct cpufreq_policy new_policy, *old_policy;
-
-    old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
-    if ( !old_policy )
-        return -EINVAL;
-
-    memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
-
-    new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
-    if (new_policy.governor == NULL)
-        return -EINVAL;
-
-    return __cpufreq_set_policy(old_policy, &new_policy);
-}
-
-static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
-{
-    int ret = 0;
-    struct cpufreq_policy *policy;
-
-    policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
-
-    if ( !policy || !policy->governor )
-        return -EINVAL;
-
-    switch(op->u.set_para.ctrl_type)
-    {
-    case SCALING_MAX_FREQ:
-    {
-        struct cpufreq_policy new_policy;
-
-        memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
-        new_policy.max = op->u.set_para.ctrl_value;
-        ret = __cpufreq_set_policy(policy, &new_policy);
-
-        break;
-    }
-
-    case SCALING_MIN_FREQ:
-    {
-        struct cpufreq_policy new_policy;
-
-        memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
-        new_policy.min = op->u.set_para.ctrl_value;
-        ret = __cpufreq_set_policy(policy, &new_policy);
-
-        break;
-    }
-
-    case SCALING_SETSPEED:
-    {
-        unsigned int freq =op->u.set_para.ctrl_value;
-
-        if ( !strnicmp(policy->governor->name,
-                       "userspace", CPUFREQ_NAME_LEN) )
-            ret = write_userspace_scaling_setspeed(op->cpuid, freq);
-        else
-            ret = -EINVAL;
-
-        break;
-    }
-
-    case SAMPLING_RATE:
-    {
-        unsigned int sampling_rate = op->u.set_para.ctrl_value;
-
-        if ( !strnicmp(policy->governor->name,
-                       "ondemand", CPUFREQ_NAME_LEN) )
-            ret = write_ondemand_sampling_rate(sampling_rate);
-        else
-            ret = -EINVAL;
-
-        break;
-    }
-
-    case UP_THRESHOLD:
-    {
-        unsigned int up_threshold = op->u.set_para.ctrl_value;
-
-        if ( !strnicmp(policy->governor->name,
-                       "ondemand", CPUFREQ_NAME_LEN) )
-            ret = write_ondemand_up_threshold(up_threshold);
-        else
-            ret = -EINVAL;
-
-        break;
-    }
-
-    default:
-        ret = -EINVAL;
-        break;
-    }
-
-    return ret;
-}
-
-int do_pm_op(struct xen_sysctl_pm_op *op)
-{
-    int ret = 0;
-    const struct processor_pminfo *pmpt;
-
-    if ( !op || op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) )
-        return -EINVAL;
-    pmpt = processor_pminfo[op->cpuid];
-
-    switch ( op->cmd & PM_PARA_CATEGORY_MASK )
-    {
-    case CPUFREQ_PARA:
-        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
-            return -ENODEV;
-        if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
-            return -EINVAL;
-        break;
-    }
-
-    switch ( op->cmd )
-    {
-    case GET_CPUFREQ_PARA:
-    {
-        ret = get_cpufreq_para(op);
-        break;
-    }
-
-    case SET_CPUFREQ_GOV:
-    {
-        ret = set_cpufreq_gov(op);
-        break;
-    }
-
-    case SET_CPUFREQ_PARA:
-    {
-        ret = set_cpufreq_para(op);
-        break;
-    }
-
-    case GET_CPUFREQ_AVGFREQ:
-    {
-        op->u.get_avgfreq = cpufreq_driver_getavg(op->cpuid, USR_GETAVG);
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_set_sched_opt_smt:
-    {
-        uint32_t saved_value;
-
-        saved_value = sched_smt_power_savings;
-        sched_smt_power_savings = !!op->u.set_sched_opt_smt;
-        op->u.set_sched_opt_smt = saved_value;
-
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_set_vcpu_migration_delay:
-    {
-        set_vcpu_migration_delay(op->u.set_vcpu_migration_delay);
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_get_vcpu_migration_delay:
-    {
-        op->u.get_vcpu_migration_delay = get_vcpu_migration_delay();
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_get_max_cstate:
-    {
-        op->u.get_max_cstate = acpi_get_cstate_limit();
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_set_max_cstate:
-    {
-        acpi_set_cstate_limit(op->u.set_max_cstate);
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_enable_turbo:
-    {
-        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
-        break;
-    }
-
-    case XEN_SYSCTL_pm_op_disable_turbo:
-    {
-        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
-        break;
-    }
-
-    default:
-        printk("not defined sub-hypercall @ do_pm_op\n");
-        ret = -ENOSYS;
-        break;
-    }
-
-    return ret;
-}
-
-int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
-{
-    u32 bits[3];
-    int ret;
-
-    if ( copy_from_guest(bits, pdc, 2) )
-        ret = -EFAULT;
-    else if ( bits[0] != ACPI_PDC_REVISION_ID || !bits[1] )
-        ret = -EINVAL;
-    else if ( copy_from_guest_offset(bits + 2, pdc, 2, 1) )
-        ret = -EFAULT;
-    else
-    {
-        u32 mask = 0;
-
-        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_CX )
-            mask |= ACPI_PDC_C_MASK | ACPI_PDC_SMP_C1PT;
-        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_PX )
-            mask |= ACPI_PDC_P_MASK | ACPI_PDC_SMP_C1PT;
-        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_TX )
-            mask |= ACPI_PDC_T_MASK | ACPI_PDC_SMP_C1PT;
-        bits[2] &= (ACPI_PDC_C_MASK | ACPI_PDC_P_MASK | ACPI_PDC_T_MASK |
-                    ACPI_PDC_SMP_C1PT) & ~mask;
-        ret = arch_acpi_set_pdc_bits(acpi_id, bits, mask);
-    }
-    if ( !ret && __copy_to_guest_offset(pdc, 2, bits + 2, 1) )
-        ret = -EFAULT;
-
-    return ret;
-}
diff --git a/xen/drivers/pm/Makefile b/xen/drivers/pm/Makefile
new file mode 100644
index 0000000..db1d37a
--- /dev/null
+++ b/xen/drivers/pm/Makefile
@@ -0,0 +1 @@
+obj-y += pmstat.o
diff --git a/xen/drivers/pm/pmstat.c b/xen/drivers/pm/pmstat.c
new file mode 100644
index 0000000..bd6ca43
--- /dev/null
+++ b/xen/drivers/pm/pmstat.c
@@ -0,0 +1,528 @@
+/*****************************************************************************
+#  pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
+#
+#  Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify it 
+# under the terms of the GNU General Public License as published by the Free 
+# Software Foundation; either version 2 of the License, or (at your option) 
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT 
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The full GNU General Public License is included in this distribution in the
+# file called LICENSE.
+#
+*****************************************************************************/
+
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <xen/irq.h>
+#include <xen/iocap.h>
+#include <xen/compat.h>
+#include <xen/guest_access.h>
+#include <asm/current.h>
+#include <public/xen.h>
+#include <xen/cpumask.h>
+#include <asm/processor.h>
+#include <xen/percpu.h>
+#include <xen/domain.h>
+#include <xen/acpi.h>
+
+#include <public/sysctl.h>
+#include <cpufreq/cpufreq.h>
+#include <xen/pmstat.h>
+
+DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
+
+/*
+ * Get PM statistic info
+ */
+int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
+{
+    int ret = 0;
+    const struct processor_pminfo *pmpt;
+
+    if ( !op || (op->cpuid >= nr_cpu_ids) || !cpu_online(op->cpuid) )
+        return -EINVAL;
+    pmpt = processor_pminfo[op->cpuid];
+
+    switch ( op->type & PMSTAT_CATEGORY_MASK )
+    {
+    case PMSTAT_CX:
+        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
+            return -ENODEV;
+        break;
+    case PMSTAT_PX:
+        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+            return -ENODEV;
+        if ( !cpufreq_driver )
+            return -ENODEV;
+        if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
+            return -EINVAL;
+        break;
+    default:
+        return -ENODEV;
+    }
+
+    switch ( op->type )
+    {
+    case PMSTAT_get_max_px:
+    {
+        op->u.getpx.total = pmpt->perf.state_count;
+        break;
+    }
+
+    case PMSTAT_get_pxstat:
+    {
+        uint32_t ct;
+        struct pm_px *pxpt;
+        spinlock_t *cpufreq_statistic_lock = 
+                   &per_cpu(cpufreq_statistic_lock, op->cpuid);
+
+        spin_lock(cpufreq_statistic_lock);
+
+        pxpt = per_cpu(cpufreq_statistic_data, op->cpuid);
+        if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
+        {
+            spin_unlock(cpufreq_statistic_lock);
+            return -ENODATA;
+        }
+
+        pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit;
+
+        cpufreq_residency_update(op->cpuid, pxpt->u.cur);
+
+        ct = pmpt->perf.state_count;
+        if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
+        {
+            spin_unlock(cpufreq_statistic_lock);
+            ret = -EFAULT;
+            break;
+        }
+
+        if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
+        {
+            spin_unlock(cpufreq_statistic_lock);
+            ret = -EFAULT;
+            break;
+        }
+
+        op->u.getpx.total = pxpt->u.total;
+        op->u.getpx.usable = pxpt->u.usable;
+        op->u.getpx.last = pxpt->u.last;
+        op->u.getpx.cur = pxpt->u.cur;
+
+        spin_unlock(cpufreq_statistic_lock);
+
+        break;
+    }
+
+    case PMSTAT_reset_pxstat:
+    {
+        cpufreq_statistic_reset(op->cpuid);
+        break;
+    }
+
+    case PMSTAT_get_max_cx:
+    {
+        op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
+        ret = 0;
+        break;
+    }
+
+    case PMSTAT_get_cxstat:
+    {
+        ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx);
+        break;
+    }
+
+    case PMSTAT_reset_cxstat:
+    {
+        ret = pmstat_reset_cx_stat(op->cpuid);
+        break;
+    }
+
+    default:
+        printk("not defined sub-hypercall @ do_get_pm_info\n");
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
+}
+
+/*
+ * 1. Get PM parameter
+ * 2. Provide user PM control
+ */
+static int read_scaling_available_governors(char *scaling_available_governors,
+                                            unsigned int size)
+{
+    unsigned int i = 0;
+    struct cpufreq_governor *t;
+
+    if ( !scaling_available_governors )
+        return -EINVAL;
+
+    list_for_each_entry(t, &cpufreq_governor_list, governor_list)
+    {
+        i += scnprintf(&scaling_available_governors[i],
+                       CPUFREQ_NAME_LEN, "%s ", t->name);
+        if ( i > size )
+            return -EINVAL;
+    }
+    scaling_available_governors[i-1] = '\0';
+
+    return 0;
+}
+
+static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
+{
+    uint32_t ret = 0;
+    const struct processor_pminfo *pmpt;
+    struct cpufreq_policy *policy;
+    uint32_t gov_num = 0;
+    uint32_t *affected_cpus;
+    uint32_t *scaling_available_frequencies;
+    char     *scaling_available_governors;
+    struct list_head *pos;
+    uint32_t cpu, i, j = 0;
+
+    pmpt = processor_pminfo[op->cpuid];
+    policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+
+    if ( !pmpt || !pmpt->perf.states ||
+         !policy || !policy->governor )
+        return -EINVAL;
+
+    list_for_each(pos, &cpufreq_governor_list)
+        gov_num++;
+
+    if ( (op->u.get_para.cpu_num  != cpumask_weight(policy->cpus)) ||
+         (op->u.get_para.freq_num != pmpt->perf.state_count)    ||
+         (op->u.get_para.gov_num  != gov_num) )
+    {
+        op->u.get_para.cpu_num =  cpumask_weight(policy->cpus);
+        op->u.get_para.freq_num = pmpt->perf.state_count;
+        op->u.get_para.gov_num  = gov_num;
+        return -EAGAIN;
+    }
+
+    if ( !(affected_cpus = xzalloc_array(uint32_t, op->u.get_para.cpu_num)) )
+        return -ENOMEM;
+    for_each_cpu(cpu, policy->cpus)
+        affected_cpus[j++] = cpu;
+    ret = copy_to_guest(op->u.get_para.affected_cpus,
+                       affected_cpus, op->u.get_para.cpu_num);
+    xfree(affected_cpus);
+    if ( ret )
+        return ret;
+
+    if ( !(scaling_available_frequencies =
+           xzalloc_array(uint32_t, op->u.get_para.freq_num)) )
+        return -ENOMEM;
+    for ( i = 0; i < op->u.get_para.freq_num; i++ )
+        scaling_available_frequencies[i] =
+                        pmpt->perf.states[i].core_frequency * 1000;
+    ret = copy_to_guest(op->u.get_para.scaling_available_frequencies,
+                   scaling_available_frequencies, op->u.get_para.freq_num);
+    xfree(scaling_available_frequencies);
+    if ( ret )
+        return ret;
+
+    if ( !(scaling_available_governors =
+           xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
+        return -ENOMEM;
+    if ( (ret = read_scaling_available_governors(scaling_available_governors,
+                gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
+    {
+        xfree(scaling_available_governors);
+        return ret;
+    }
+    ret = copy_to_guest(op->u.get_para.scaling_available_governors,
+                scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
+    xfree(scaling_available_governors);
+    if ( ret )
+        return ret;
+
+    op->u.get_para.cpuinfo_cur_freq =
+        cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
+    op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
+    op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
+    op->u.get_para.scaling_cur_freq = policy->cur;
+    op->u.get_para.scaling_max_freq = policy->max;
+    op->u.get_para.scaling_min_freq = policy->min;
+
+    if ( cpufreq_driver->name[0] )
+        strlcpy(op->u.get_para.scaling_driver, 
+            cpufreq_driver->name, CPUFREQ_NAME_LEN);
+    else
+        strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
+
+    if ( policy->governor->name[0] )
+        strlcpy(op->u.get_para.scaling_governor, 
+            policy->governor->name, CPUFREQ_NAME_LEN);
+    else
+        strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
+
+    /* governor specific para */
+    if ( !strnicmp(op->u.get_para.scaling_governor, 
+                   "userspace", CPUFREQ_NAME_LEN) )
+    {
+        op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
+    }
+
+    if ( !strnicmp(op->u.get_para.scaling_governor, 
+                   "ondemand", CPUFREQ_NAME_LEN) )
+    {
+        ret = get_cpufreq_ondemand_para(
+            &op->u.get_para.u.ondemand.sampling_rate_max,
+            &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.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
+
+    return ret;
+}
+
+static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
+{
+    struct cpufreq_policy new_policy, *old_policy;
+
+    old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+    if ( !old_policy )
+        return -EINVAL;
+
+    memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
+
+    new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
+    if (new_policy.governor == NULL)
+        return -EINVAL;
+
+    return __cpufreq_set_policy(old_policy, &new_policy);
+}
+
+static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
+{
+    int ret = 0;
+    struct cpufreq_policy *policy;
+
+    policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+
+    if ( !policy || !policy->governor )
+        return -EINVAL;
+
+    switch(op->u.set_para.ctrl_type)
+    {
+    case SCALING_MAX_FREQ:
+    {
+        struct cpufreq_policy new_policy;
+
+        memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+        new_policy.max = op->u.set_para.ctrl_value;
+        ret = __cpufreq_set_policy(policy, &new_policy);
+
+        break;
+    }
+
+    case SCALING_MIN_FREQ:
+    {
+        struct cpufreq_policy new_policy;
+
+        memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+        new_policy.min = op->u.set_para.ctrl_value;
+        ret = __cpufreq_set_policy(policy, &new_policy);
+
+        break;
+    }
+
+    case SCALING_SETSPEED:
+    {
+        unsigned int freq =op->u.set_para.ctrl_value;
+
+        if ( !strnicmp(policy->governor->name,
+                       "userspace", CPUFREQ_NAME_LEN) )
+            ret = write_userspace_scaling_setspeed(op->cpuid, freq);
+        else
+            ret = -EINVAL;
+
+        break;
+    }
+
+    case SAMPLING_RATE:
+    {
+        unsigned int sampling_rate = op->u.set_para.ctrl_value;
+
+        if ( !strnicmp(policy->governor->name,
+                       "ondemand", CPUFREQ_NAME_LEN) )
+            ret = write_ondemand_sampling_rate(sampling_rate);
+        else
+            ret = -EINVAL;
+
+        break;
+    }
+
+    case UP_THRESHOLD:
+    {
+        unsigned int up_threshold = op->u.set_para.ctrl_value;
+
+        if ( !strnicmp(policy->governor->name,
+                       "ondemand", CPUFREQ_NAME_LEN) )
+            ret = write_ondemand_up_threshold(up_threshold);
+        else
+            ret = -EINVAL;
+
+        break;
+    }
+
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+int do_pm_op(struct xen_sysctl_pm_op *op)
+{
+    int ret = 0;
+    const struct processor_pminfo *pmpt;
+
+    if ( !op || op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) )
+        return -EINVAL;
+    pmpt = processor_pminfo[op->cpuid];
+
+    switch ( op->cmd & PM_PARA_CATEGORY_MASK )
+    {
+    case CPUFREQ_PARA:
+        if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+            return -ENODEV;
+        if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
+            return -EINVAL;
+        break;
+    }
+
+    switch ( op->cmd )
+    {
+    case GET_CPUFREQ_PARA:
+    {
+        ret = get_cpufreq_para(op);
+        break;
+    }
+
+    case SET_CPUFREQ_GOV:
+    {
+        ret = set_cpufreq_gov(op);
+        break;
+    }
+
+    case SET_CPUFREQ_PARA:
+    {
+        ret = set_cpufreq_para(op);
+        break;
+    }
+
+    case GET_CPUFREQ_AVGFREQ:
+    {
+        op->u.get_avgfreq = cpufreq_driver_getavg(op->cpuid, USR_GETAVG);
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_set_sched_opt_smt:
+    {
+        uint32_t saved_value;
+
+        saved_value = sched_smt_power_savings;
+        sched_smt_power_savings = !!op->u.set_sched_opt_smt;
+        op->u.set_sched_opt_smt = saved_value;
+
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_set_vcpu_migration_delay:
+    {
+        set_vcpu_migration_delay(op->u.set_vcpu_migration_delay);
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_get_vcpu_migration_delay:
+    {
+        op->u.get_vcpu_migration_delay = get_vcpu_migration_delay();
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_get_max_cstate:
+    {
+        op->u.get_max_cstate = acpi_get_cstate_limit();
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_set_max_cstate:
+    {
+        acpi_set_cstate_limit(op->u.set_max_cstate);
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_enable_turbo:
+    {
+        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_disable_turbo:
+    {
+        ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
+        break;
+    }
+
+    default:
+        printk("not defined sub-hypercall @ do_pm_op\n");
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
+}
+
+int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
+{
+    u32 bits[3];
+    int ret;
+
+    if ( copy_from_guest(bits, pdc, 2) )
+        ret = -EFAULT;
+    else if ( bits[0] != ACPI_PDC_REVISION_ID || !bits[1] )
+        ret = -EINVAL;
+    else if ( copy_from_guest_offset(bits + 2, pdc, 2, 1) )
+        ret = -EFAULT;
+    else
+    {
+        u32 mask = 0;
+
+        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_CX )
+            mask |= ACPI_PDC_C_MASK | ACPI_PDC_SMP_C1PT;
+        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_PX )
+            mask |= ACPI_PDC_P_MASK | ACPI_PDC_SMP_C1PT;
+        if ( xen_processor_pmbits & XEN_PROCESSOR_PM_TX )
+            mask |= ACPI_PDC_T_MASK | ACPI_PDC_SMP_C1PT;
+        bits[2] &= (ACPI_PDC_C_MASK | ACPI_PDC_P_MASK | ACPI_PDC_T_MASK |
+                    ACPI_PDC_SMP_C1PT) & ~mask;
+        ret = arch_acpi_set_pdc_bits(acpi_id, bits, mask);
+    }
+    if ( !ret && __copy_to_guest_offset(pdc, 2, bits + 2, 1) )
+        ret = -EFAULT;
+
+    return ret;
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (2 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:39   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable Oleksandr Dmytryshyn
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

This settings is x86-specific and should not be used for
other architectures.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/drivers/cpufreq/utility.c | 11 ++++++++++-
 xen/drivers/pm/pmstat.c       |  6 ++++++
 xen/include/cpufreq/cpufreq.h |  6 ++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c
index c9150a1..d01c768 100644
--- a/xen/drivers/cpufreq/utility.c
+++ b/xen/drivers/cpufreq/utility.c
@@ -209,7 +209,9 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
 {
     unsigned int min_freq = ~0;
     unsigned int max_freq = 0;
+#ifdef CONFIG_X86
     unsigned int second_max_freq = 0;
+#endif
     unsigned int i;
 
     for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
@@ -221,6 +223,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
         if (freq > max_freq)
             max_freq = freq;
     }
+#ifdef CONFIG_X86
     for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
         unsigned int freq = table[i].frequency;
         if (freq == CPUFREQ_ENTRY_INVALID || freq == max_freq)
@@ -234,9 +237,13 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
         printk("max_freq: %u    second_max_freq: %u\n",
                max_freq, second_max_freq);
 
+    policy->cpuinfo.second_max_freq = second_max_freq;
+#else
+    if (cpufreq_verbose)
+        printk("max_freq: %u\n", max_freq);
+#endif
     policy->min = policy->cpuinfo.min_freq = min_freq;
     policy->max = policy->cpuinfo.max_freq = max_freq;
-    policy->cpuinfo.second_max_freq = second_max_freq;
 
     if (policy->min == ~0)
         return -EINVAL;
@@ -390,6 +397,7 @@ int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag)
     return policy->cur;
 }
 
+#ifdef CONFIG_X86
 int cpufreq_update_turbo(int cpuid, int new_state)
 {
     struct cpufreq_policy *policy;
@@ -430,6 +438,7 @@ int cpufreq_get_turbo_status(int cpuid)
     policy = per_cpu(cpufreq_cpu_policy, cpuid);
     return policy && policy->turbo == CPUFREQ_TURBO_ENABLED;
 }
+#endif /* CONFIG_X86 */
 
 /*********************************************************************
  *                 POLICY                                            *
diff --git a/xen/drivers/pm/pmstat.c b/xen/drivers/pm/pmstat.c
index bd6ca43..fff3609 100644
--- a/xen/drivers/pm/pmstat.c
+++ b/xen/drivers/pm/pmstat.c
@@ -292,7 +292,11 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
             &op->u.get_para.u.ondemand.sampling_rate,
             &op->u.get_para.u.ondemand.up_threshold);
     }
+#ifdef CONFIG_X86
     op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
+#else
+    op->u.get_para.turbo_enabled = 0;
+#endif
 
     return ret;
 }
@@ -475,6 +479,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
         break;
     }
 
+#ifdef CONFIG_X86
     case XEN_SYSCTL_pm_op_enable_turbo:
     {
         ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
@@ -486,6 +491,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
         ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
         break;
     }
+#endif /* CONFIG_X86 */
 
     default:
         printk("not defined sub-hypercall @ do_pm_op\n");
diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
index dde7259..88ada16 100644
--- a/xen/include/cpufreq/cpufreq.h
+++ b/xen/include/cpufreq/cpufreq.h
@@ -39,7 +39,9 @@ extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
 
 struct cpufreq_cpuinfo {
     unsigned int        max_freq;
+#ifdef CONFIG_X86
     unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
+#endif
     unsigned int        min_freq;
     unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
 };
@@ -59,10 +61,12 @@ struct cpufreq_policy {
 
     bool_t              resume; /* flag for cpufreq 1st run
                                  * S3 wakeup, hotplug cpu, etc */
+#ifdef CONFIG_X86
     s8                  turbo;  /* tristate flag: 0 for unsupported
                                  * -1 for disable, 1 for enabled
                                  * See CPUFREQ_TURBO_* below for defines */
     bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
+#endif
 };
 DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
 
@@ -127,8 +131,10 @@ extern int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag);
 #define CPUFREQ_TURBO_UNSUPPORTED   0
 #define CPUFREQ_TURBO_ENABLED       1
 
+#ifdef CONFIG_X86
 extern int cpufreq_update_turbo(int cpuid, int new_state);
 extern int cpufreq_get_turbo_status(int cpuid);
+#endif
 
 static __inline__ int 
 __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (3 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:40   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 06/13] cpufreq: make cpufreq driver " Oleksandr Dmytryshyn
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

ACPI-specific and x86 specific parts are moved under
appropriate ifdefs. Now pmstat functions can be used
in ARM platform.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/drivers/pm/pmstat.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/pm/pmstat.c b/xen/drivers/pm/pmstat.c
index fff3609..7063d02 100644
--- a/xen/drivers/pm/pmstat.c
+++ b/xen/drivers/pm/pmstat.c
@@ -37,7 +37,6 @@
 #include <asm/processor.h>
 #include <xen/percpu.h>
 #include <xen/domain.h>
-#include <xen/acpi.h>
 
 #include <public/sysctl.h>
 #include <cpufreq/cpufreq.h>
@@ -133,7 +132,8 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
         cpufreq_statistic_reset(op->cpuid);
         break;
     }
-
+/* For now those operations are supported only for X86 */
+#ifdef CONFIG_X86
     case PMSTAT_get_max_cx:
     {
         op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
@@ -152,6 +152,7 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
         ret = pmstat_reset_cx_stat(op->cpuid);
         break;
     }
+#endif /* CONFIG_X86 */
 
     default:
         printk("not defined sub-hypercall @ do_get_pm_info\n");
@@ -467,6 +468,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
         break;
     }
 
+#ifdef CONFIG_ACPI
     case XEN_SYSCTL_pm_op_get_max_cstate:
     {
         op->u.get_max_cstate = acpi_get_cstate_limit();
@@ -478,6 +480,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
         acpi_set_cstate_limit(op->u.set_max_cstate);
         break;
     }
+#endif /* CONFIG_ACPI */
 
 #ifdef CONFIG_X86
     case XEN_SYSCTL_pm_op_enable_turbo:
@@ -502,6 +505,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
     return ret;
 }
 
+#ifdef CONFIG_ACPI
 int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
 {
     u32 bits[3];
@@ -532,3 +536,4 @@ int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
 
     return ret;
 }
+#endif /* CONFIG_ACPI */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 06/13] cpufreq: make cpufreq driver more generalizable
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (4 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:42   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 07/13] xen/arm: enable cpu hotplug Oleksandr Dmytryshyn
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

First implementation of the cpufreq driver has been
written with x86 in mind. This patch makes possible
the cpufreq driver be working on both x86 and arm
architectures.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/Rules.mk                         |  1 +
 xen/drivers/cpufreq/cpufreq.c        | 46 ++++++++++++++++++++++++++++++++----
 xen/include/cpufreq/processor_perf.h |  7 ++++++
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index b7caab6..23045bb 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -55,6 +55,7 @@ CFLAGS-$(perfc)         += -DPERF_COUNTERS
 CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
 CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
 CFLAGS-$(HAS_ACPI)      += -DHAS_ACPI
+CFLAGS-$(HAS_CPUFREQ)   += -DHAS_CPUFREQ
 CFLAGS-$(HAS_PM)        += -DHAS_PM
 CFLAGS-$(HAS_GDBSX)     += -DHAS_GDBSX
 CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index 884d2bb..30ff5b8 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -43,9 +43,14 @@
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/percpu.h>
-#include <acpi/acpi.h>
 #include <cpufreq/cpufreq.h>
 
+#ifdef CONFIG_ACPI
+    #define XEN_PX_FULL_INIT (XEN_PX_PCT | XEN_PX_PSS | XEN_PX_PSD | XEN_PX_PPC)
+#else
+    #define XEN_PX_FULL_INIT (XEN_PX_PSS | XEN_PX_PSD | XEN_PX_PPC)
+#endif
+
 static unsigned int __read_mostly usr_min_freq;
 static unsigned int __read_mostly usr_max_freq;
 static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy);
@@ -192,6 +197,7 @@ int cpufreq_add_cpu(unsigned int cpu)
     } else {
         /* domain sanity check under whatever coordination type */
         firstcpu = cpumask_first(cpufreq_dom->map);
+#ifdef CONFIG_ACPI
         if ((perf->domain_info.coord_type !=
             processor_pminfo[firstcpu]->perf.domain_info.coord_type) ||
             (perf->domain_info.num_processors !=
@@ -207,6 +213,18 @@ int cpufreq_add_cpu(unsigned int cpu)
                 );
             return -EINVAL;
         }
+#else /* CONFIG_ACPI */
+        if ((perf->domain_info.num_processors !=
+            processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
+
+            printk(KERN_WARNING "cpufreq fail to add CPU%d:"
+                   "incorrect _PSD(%"PRIu64"), expect(%"PRIu64")\n",
+                   cpu, perf->domain_info.num_processors,
+                   processor_pminfo[firstcpu]->perf.domain_info.num_processors
+                );
+            return -EINVAL;
+        }
+#endif /* CONFIG_ACPI */
     }
 
     if (!domexist || hw_all) {
@@ -363,6 +381,7 @@ int cpufreq_del_cpu(unsigned int cpu)
     return 0;
 }
 
+#ifdef CONFIG_ACPI
 static void print_PCT(struct xen_pct_register *ptr)
 {
     printk("\t_PCT: descriptor=%d, length=%d, space_id=%d, "
@@ -370,12 +389,14 @@ static void print_PCT(struct xen_pct_register *ptr)
            ptr->descriptor, ptr->length, ptr->space_id, ptr->bit_width,
            ptr->bit_offset, ptr->reserved, ptr->address);
 }
+#endif
 
 static void print_PSS(struct xen_processor_px *ptr, int count)
 {
     int i;
     printk("\t_PSS: state_count=%d\n", count);
     for (i=0; i<count; i++){
+#ifdef CONFIG_ACPI
         printk("\tState%d: %"PRId64"MHz %"PRId64"mW %"PRId64"us "
                "%"PRId64"us %#"PRIx64" %#"PRIx64"\n",
                i,
@@ -385,15 +406,26 @@ static void print_PSS(struct xen_processor_px *ptr, int count)
                ptr[i].bus_master_latency,
                ptr[i].control,
                ptr[i].status);
+#else /* CONFIG_ACPI */
+        printk("\tState%d: %"PRId64"MHz %"PRId64"us\n",
+               i,
+               ptr[i].core_frequency,
+               ptr[i].transition_latency);
+#endif /* CONFIG_ACPI */
     }
 }
 
 static void print_PSD( struct xen_psd_package *ptr)
 {
+#ifdef CONFIG_ACPI
     printk("\t_PSD: num_entries=%"PRId64" rev=%"PRId64
            " domain=%"PRId64" coord_type=%"PRId64" num_processors=%"PRId64"\n",
            ptr->num_entries, ptr->revision, ptr->domain, ptr->coord_type,
            ptr->num_processors);
+#else /* CONFIG_ACPI */
+    printk("\t_PSD:  domain=%"PRId64" num_processors=%"PRId64"\n",
+           ptr->domain, ptr->num_processors);
+#endif /* CONFIG_ACPI */
 }
 
 static void print_PPC(unsigned int platform_limit)
@@ -407,7 +439,11 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
     struct processor_pminfo *pmpt;
     struct processor_performance *pxpt;
 
+#ifdef CONFIG_ACPI
     cpuid = get_cpu_id(acpi_id);
+#else
+    cpuid = acpi_id;
+#endif
     if ( cpuid < 0 || !dom0_px_info)
     {
         ret = -EINVAL;
@@ -429,6 +465,8 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
         processor_pminfo[cpuid] = pmpt;
     }
     pxpt = &pmpt->perf;
+
+#ifdef CONFIG_ACPI
     pmpt->acpi_id = acpi_id;
     pmpt->id = cpuid;
 
@@ -455,7 +493,7 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
             print_PCT(&pxpt->status_register);
         }
     }
-
+#endif /* CONFIG_ACPI */
     if ( dom0_px_info->flags & XEN_PX_PSS ) 
     {
         /* capability check */
@@ -517,11 +555,9 @@ int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
         }
     }
 
-    if ( dom0_px_info->flags == ( XEN_PX_PCT | XEN_PX_PSS |
-                XEN_PX_PSD | XEN_PX_PPC ) )
+    if ( dom0_px_info->flags == XEN_PX_FULL_INIT )
     {
         pxpt->init = XEN_PX_INIT;
-
         ret = cpufreq_cpu_init(cpuid);
         goto out;
     }
diff --git a/xen/include/cpufreq/processor_perf.h b/xen/include/cpufreq/processor_perf.h
index d8a1ba6..6c1279d 100644
--- a/xen/include/cpufreq/processor_perf.h
+++ b/xen/include/cpufreq/processor_perf.h
@@ -3,7 +3,10 @@
 
 #include <public/platform.h>
 #include <public/sysctl.h>
+
+#ifdef CONFIG_ACPI
 #include <xen/acpi.h>
+#endif
 
 #define XEN_PX_INIT 0x80000000
 
@@ -24,8 +27,10 @@ int  cpufreq_del_cpu(unsigned int);
 struct processor_performance {
     uint32_t state;
     uint32_t platform_limit;
+#ifdef CONFIG_ACPI
     struct xen_pct_register control_register;
     struct xen_pct_register status_register;
+#endif
     uint32_t state_count;
     struct xen_processor_px *states;
     struct xen_psd_package domain_info;
@@ -35,8 +40,10 @@ struct processor_performance {
 };
 
 struct processor_pminfo {
+#ifdef CONFIG_ACPI
     uint32_t acpi_id;
     uint32_t id;
+#endif
     struct processor_performance    perf;
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 07/13] xen/arm: enable cpu hotplug
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (5 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 06/13] cpufreq: make cpufreq driver " Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 15:15   ` Julien Grall
  2014-10-07 14:19 ` [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global Oleksandr Dmytryshyn
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

This config is needed for the cpufreq driver.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/include/asm-arm/config.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index 5b7b1a8..ca17c79 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -203,6 +203,9 @@ extern unsigned long frametable_virt_end;
 #define GIC_VR_OFFSET 0x6000 /* Virtual Machine CPU interface) */
 #endif /* __ASSEMBLY__ */
 
+#define CONFIG_HOTPLUG 1
+#define CONFIG_HOTPLUG_CPU 1
+
 #endif /* __ARM_CONFIG_H__ */
 /*
  * Local variables:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (6 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 07/13] xen/arm: enable cpu hotplug Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 15:09   ` Julien Grall
  2014-10-07 14:19 ` [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver Oleksandr Dmytryshyn
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

This patch makes possible to use the dt_find_property function
outside the device tree module.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/common/device_tree.c      | 2 +-
 xen/include/xen/device_tree.h | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index f0bd7b9..5fbb0c1 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -522,7 +522,7 @@ static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 }
 
 /* Find a property with a given name for a given node and return it. */
-static const struct dt_property *
+const struct dt_property *
 dt_find_property(const struct dt_device_node *np,
                  const char *name,
                  u32 *lenp)
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 99de53f..508d840 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -344,6 +344,15 @@ struct dt_device_node *dt_find_compatible_node(struct dt_device_node *from,
 
 /**
  * Find a property with a given name for a given node
+ * and return it.
+ */
+const struct dt_property *dt_find_property(const struct dt_device_node *np,
+                                           const char *name,
+                                           u32 *lenp);
+
+
+/**
+ * Find a property with a given name for a given node
  * and return the value.
  */
 const void *dt_get_property(const struct dt_device_node *np,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (7 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 15:26   ` Julien Grall
  2014-10-07 14:19 ` [RFC PATCH 10/13] xen: arm: implement platform hypercall Oleksandr Dmytryshyn
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

This patch copies all cpu@0..cpu@N nodes (from input
device tree) with properties to /cpus/cpu@0/private_data
node (device tree for Dom0). Thus we can have any number
of VCPUs in Dom0 and we give all information about all
physical CPUs in the private_data node. Driver in Dom0
should parse /cpus/cpu@0/private_data path instead of the
/cpus path in the device tree.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/arch/arm/domain_build.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 2db0236..a142cc4 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -436,6 +436,10 @@ static int make_cpus_node(const struct domain *d, void *fdt,
     char buf[15];
     u32 clock_frequency;
     bool_t clock_valid;
+#ifdef HAS_CPUFREQ
+    const struct dt_property *pp;
+    char *node_name;
+#endif
 
     DPRINT("Create cpus node\n");
 
@@ -517,6 +521,60 @@ static int make_cpus_node(const struct domain *d, void *fdt,
                 return res;
         }
 
+#ifdef HAS_CPUFREQ
+        /*
+         * Add "private_data" node to cpu@0 and copy to it
+         * original cpu@0..cpu@N nodes with its properties.
+         * This is needed for the cpufreq cpu driver in Dom0
+         */
+        if ( cpu == 0 )
+        {
+            DPRINT("Create private_data node\n");
+
+            res = fdt_begin_node(fdt, "private_data");
+            if ( res )
+                return res;
+
+            dt_for_each_child_node( cpus, npcpu )
+            {
+                if ( dt_device_type_is_equal(npcpu, "cpu") )
+                {
+                    node_name = strrchr(dt_node_full_name(npcpu), '/');
+                    if ( node_name )
+                        node_name++;
+
+                    if ( node_name && *node_name )
+                    {
+                        DPRINT("Copy %s node to the private_data\n", node_name);
+
+                        res = fdt_begin_node(fdt, node_name);
+                        if ( res )
+                            return res;
+
+                        dt_for_each_property_node( npcpu, pp )
+                        {
+                            if ( pp->length )
+                            {
+                                res = fdt_property(fdt, pp->name, pp->value,
+                                                   pp->length);
+                                if ( res )
+                                    return res;
+                            }
+                        }
+
+                        res = fdt_end_node(fdt);
+                        if ( res )
+                            return res;
+                    }
+                }
+            }
+
+            res = fdt_end_node(fdt);
+            if ( res )
+                return res;
+        }
+#endif /* HAS_CPUFREQ */
+
         res = fdt_end_node(fdt);
         if ( res )
             return res;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 10/13] xen: arm: implement platform hypercall
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (8 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 15:39   ` Julien Grall
  2014-10-07 14:19 ` [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver Oleksandr Dmytryshyn
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/arch/arm/Makefile             |  1 +
 xen/arch/arm/platform_hypercall.c | 98 +++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/traps.c              |  1 +
 3 files changed, 100 insertions(+)
 create mode 100644 xen/arch/arm/platform_hypercall.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index d70f6d5..332528f 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -20,6 +20,7 @@ obj-y += percpu.o
 obj-y += guestcopy.o
 obj-y += physdev.o
 obj-y += platform.o
+obj-y += platform_hypercall.o
 obj-y += setup.o
 obj-y += time.o
 obj-y += smpboot.o
diff --git a/xen/arch/arm/platform_hypercall.c b/xen/arch/arm/platform_hypercall.c
new file mode 100644
index 0000000..b4ad039
--- /dev/null
+++ b/xen/arch/arm/platform_hypercall.c
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * platform_hypercall.c
+ *
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ *
+ * Copyright (c) 2002-2006, K Fraser
+ * Copyright (c) 2014, GlobalLogic Inc.
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/domain.h>
+#include <xen/event.h>
+#include <xen/guest_access.h>
+#include <xen/pmstat.h>
+#include <xen/irq.h>
+#include <public/platform.h>
+#include <cpufreq/processor_perf.h>
+#include <xsm/xsm.h>
+
+#ifndef COMPAT
+typedef long ret_t;
+DEFINE_SPINLOCK(xenpf_lock);
+# undef copy_from_compat
+# define copy_from_compat copy_from_guest
+# undef copy_to_compat
+# define copy_to_compat copy_to_guest
+# undef guest_from_compat_handle
+# define guest_from_compat_handle(x,y) ((x)=(y))
+#else
+extern spinlock_t xenpf_lock;
+#endif
+
+ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
+{
+    ret_t ret = 0;
+    struct xen_platform_op curop, *op = &curop;
+
+    if ( copy_from_guest(op, u_xenpf_op, 1) )
+        return -EFAULT;
+
+    if ( op->interface_version != XENPF_INTERFACE_VERSION )
+        return -EACCES;
+
+    /*
+     * Trylock here avoids deadlock with an existing platform critical section
+     * which might (for some current or future reason) want to synchronise
+     * with this vcpu.
+     */
+    while ( !spin_trylock(&xenpf_lock) )
+        if ( hypercall_preempt_check() )
+            return hypercall_create_continuation(
+                __HYPERVISOR_platform_op, "h", u_xenpf_op);
+
+    switch ( op->cmd )
+    {
+    case XENPF_set_processor_pminfo:
+        switch ( op->u.set_pminfo.type )
+        {
+        case XEN_PM_PX:
+            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+            {
+                ret = -ENOSYS;
+                break;
+            }
+#ifdef HAS_CPUFREQ
+            ret = set_px_pminfo(op->u.set_pminfo.id, &op->u.set_pminfo.u.perf);
+#else
+            ret = -EINVAL;
+#endif
+            break;
+
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+    default:
+        ret = -ENOSYS;
+        break;
+    }
+
+    spin_unlock(&xenpf_lock);
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 21c7b26..d1b0014 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1012,6 +1012,7 @@ static arm_hypercall_t arm_hypercall_table[] = {
     HYPERCALL(hvm_op, 2),
     HYPERCALL(grant_table_op, 3),
     HYPERCALL_ARM(vcpu_op, 3),
+    HYPERCALL(platform_op, 1),
 };
 
 typedef int (*arm_psci_fn_t)(uint32_t, register_t);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (9 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 10/13] xen: arm: implement platform hypercall Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:44   ` Jan Beulich
  2014-10-07 14:19 ` [RFC PATCH 12/13] xen: arm: implement XEN_SYSCTL_cpufreq_op Oleksandr Dmytryshyn
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

This driver uses Dom0 to change frequencies on CPUs

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/Rules.mk                      |   1 +
 xen/drivers/cpufreq/Makefile      |   1 +
 xen/drivers/cpufreq/xen-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++++++
 xen/include/public/xen.h          |   1 +
 4 files changed, 244 insertions(+)
 create mode 100644 xen/drivers/cpufreq/xen-cpufreq.c

diff --git a/xen/Rules.mk b/xen/Rules.mk
index 23045bb..e3bc77f 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -56,6 +56,7 @@ CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
 CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
 CFLAGS-$(HAS_ACPI)      += -DHAS_ACPI
 CFLAGS-$(HAS_CPUFREQ)   += -DHAS_CPUFREQ
+CFLAGS-$(HAS_XEN_CPUFREQ) += -DHAS_XEN_CPUFREQ
 CFLAGS-$(HAS_PM)        += -DHAS_PM
 CFLAGS-$(HAS_GDBSX)     += -DHAS_GDBSX
 CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
diff --git a/xen/drivers/cpufreq/Makefile b/xen/drivers/cpufreq/Makefile
index b87d127..673edba 100644
--- a/xen/drivers/cpufreq/Makefile
+++ b/xen/drivers/cpufreq/Makefile
@@ -2,3 +2,4 @@ obj-y += cpufreq.o
 obj-y += cpufreq_ondemand.o
 obj-y += cpufreq_misc_governors.o
 obj-y += utility.o
+obj-$(HAS_XEN_CPUFREQ) += xen-cpufreq.o
diff --git a/xen/drivers/cpufreq/xen-cpufreq.c b/xen/drivers/cpufreq/xen-cpufreq.c
new file mode 100644
index 0000000..854955b
--- /dev/null
+++ b/xen/drivers/cpufreq/xen-cpufreq.c
@@ -0,0 +1,241 @@
+/*
+ *  Copyright (C) 2014 GlobalLogic Inc.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <xen/types.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <xen/irq.h>
+#include <xen/spinlock.h>
+#include <asm/current.h>
+#include <cpufreq/cpufreq.h>
+
+struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
+static DEFINE_SPINLOCK(sysctl_cpufreq_lock);
+
+struct sysctl_cpufreq_data {
+    uint32_t cpu;
+    uint32_t freq;
+    uint32_t relation;
+    int32_t result;
+};
+
+static struct sysctl_cpufreq_data sysctl_cpufreq_data;
+
+int cpufreq_cpu_init(unsigned int cpuid)
+{
+    return cpufreq_add_cpu(cpuid);
+}
+
+static void notify_cpufreq_domains(void)
+{
+    send_global_virq(VIRQ_CPUFREQ);
+}
+
+static int xen_cpufreq_verify(struct cpufreq_policy *policy)
+{
+    struct acpi_cpufreq_data *data;
+    struct processor_performance *perf;
+
+    if ( !policy || !(data = cpufreq_drv_data[policy->cpu]) ||
+         !processor_pminfo[policy->cpu] )
+        return -EINVAL;
+
+    perf = &processor_pminfo[policy->cpu]->perf;
+
+    cpufreq_verify_within_limits(policy, 0,
+        perf->states[perf->platform_limit].core_frequency * 1000);
+
+    return cpufreq_frequency_table_verify(policy, data->freq_table);
+}
+
+static int xen_cpufreq_target(struct cpufreq_policy *policy,
+                               unsigned int target_freq, unsigned int relation)
+{
+    struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu];
+    struct processor_performance *perf;
+    struct cpufreq_freqs freqs;
+    cpumask_t online_policy_cpus;
+    unsigned int next_state = 0; /* Index into freq_table */
+    unsigned int next_perf_state = 0; /* Index into perf table */
+    unsigned int j;
+    int ret = 0;
+
+    if ( unlikely(data == NULL ||
+         data->acpi_data == NULL || data->freq_table == NULL) )
+    {
+        return -ENODEV;
+    }
+
+    perf = data->acpi_data;
+    ret = cpufreq_frequency_table_target(policy,
+                                            data->freq_table,
+                                            target_freq,
+                                            relation, &next_state);
+    if ( unlikely(ret) )
+        return -ENODEV;
+
+    cpumask_and(&online_policy_cpus, &cpu_online_map, policy->cpus);
+
+    next_perf_state = data->freq_table[next_state].index;
+    if ( perf->state == next_perf_state )
+    {
+        if ( unlikely(policy->resume) )
+            policy->resume = 0;
+        else
+            return 0;
+    }
+
+    freqs.old = perf->states[perf->state].core_frequency * 1000;
+    freqs.new = data->freq_table[next_state].frequency;
+
+    /* Do send cmd for Dom0 */
+    spin_lock(&sysctl_cpufreq_lock);
+    /* return previous result */
+    ret = sysctl_cpufreq_data.result;
+
+    sysctl_cpufreq_data.cpu = policy->cpu;
+    sysctl_cpufreq_data.freq = freqs.new;
+    sysctl_cpufreq_data.relation = (uint32_t)relation;
+    spin_unlock(&sysctl_cpufreq_lock);
+    notify_cpufreq_domains();
+
+    for_each_cpu( j, &online_policy_cpus )
+        cpufreq_statistic_update(j, perf->state, next_perf_state);
+
+    perf->state = next_perf_state;
+    policy->cur = freqs.new;
+
+    return ret;
+}
+
+static int
+xen_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+    struct processor_performance *perf;
+    struct acpi_cpufreq_data *data;
+    unsigned int cpu = policy->cpu;
+    unsigned int valid_states = 0;
+    int i;
+    int ret = 0;
+
+    data = xzalloc(struct acpi_cpufreq_data);
+    if ( !data )
+        return -ENOMEM;
+
+    cpufreq_drv_data[cpu] = data;
+
+    data->acpi_data = &processor_pminfo[cpu]->perf;
+
+    perf = data->acpi_data;
+    policy->shared_type = perf->shared_type;
+
+    data->freq_table = xmalloc_array(struct cpufreq_frequency_table,
+                                    (perf->state_count+1));
+    if ( !data->freq_table )
+    {
+        ret = -ENOMEM;
+        goto err_unreg;
+    }
+
+    /* detect transition latency */
+    policy->cpuinfo.transition_latency = 0;
+    for ( i=0; i<perf->state_count; i++ )
+    {
+        if ( (perf->states[i].transition_latency * 1000) >
+             policy->cpuinfo.transition_latency )
+            policy->cpuinfo.transition_latency =
+                perf->states[i].transition_latency * 1000;
+    }
+
+    policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR;
+
+    /* table init */
+    for ( i=0; i<perf->state_count; i++ )
+    {
+        if ( i>0 && perf->states[i].core_frequency >=
+            data->freq_table[valid_states-1].frequency / 1000 )
+            continue;
+
+        data->freq_table[valid_states].index = i;
+        data->freq_table[valid_states].frequency =
+            perf->states[i].core_frequency * 1000;
+        valid_states++;
+    }
+    data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
+    perf->state = 0;
+
+    ret = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
+    if ( ret )
+        goto err_freqfree;
+
+
+    /*
+     * the first call to ->target() should result in us actually
+     * send command to the Dom0 to set frequency.
+     */
+    policy->resume = 1;
+
+    /* Set the minimal frequency */
+    return xen_cpufreq_target(policy, policy->min, CPUFREQ_RELATION_L);
+
+err_freqfree:
+    xfree(data->freq_table);
+err_unreg:
+    xfree(data);
+    cpufreq_drv_data[cpu] = NULL;
+
+    return ret;
+}
+
+static int xen_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+    struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu];
+
+    if ( data )
+    {
+        cpufreq_drv_data[policy->cpu] = NULL;
+        xfree(data->freq_table);
+        xfree(data);
+    }
+
+    return 0;
+}
+
+static struct cpufreq_driver xen_cpufreq_driver = {
+    .name   = "xen-cpufreq",
+    .verify = xen_cpufreq_verify,
+    .target = xen_cpufreq_target,
+    .init   = xen_cpufreq_cpu_init,
+    .exit   = xen_cpufreq_cpu_exit,
+};
+
+int __init xen_cpufreq_driver_init(void)
+{
+    int ret = 0;
+
+    if ( cpufreq_controller == FREQCTL_xen )
+        ret = cpufreq_register_driver(&xen_cpufreq_driver);
+
+    return ret;
+}
+
+__initcall(xen_cpufreq_driver_init);
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index 8c5697e..86dd479 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -160,6 +160,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
 #define VIRQ_MEM_EVENT  10 /* G. (DOM0) A memory event has occured           */
 #define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient                     */
 #define VIRQ_ENOMEM     12 /* G. (DOM0) Low on heap memory       */
+#define VIRQ_CPUFREQ    13 /* G. (DOM0) Notify xen-cpufreq driver.           */
 
 /* Architecture-specific VIRQ definitions. */
 #define VIRQ_ARCH_0    16
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 12/13] xen: arm: implement XEN_SYSCTL_cpufreq_op
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (10 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:19 ` [RFC PATCH 13/13] xen/arm: enable cpufreq functionality for ARM Oleksandr Dmytryshyn
  2014-10-07 14:34 ` [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Jan Beulich
  13 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Kernel uses this op to get some parameters for the
xen-cpufreq driver to change CPUs frequency.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/common/sysctl.c               |  8 ++++++++
 xen/drivers/cpufreq/xen-cpufreq.c | 26 ++++++++++++++++++++++++++
 xen/include/cpufreq/cpufreq.h     |  5 +++++
 xen/include/public/sysctl.h       | 19 +++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 0dcf06a..ecdc962 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -27,6 +27,7 @@
 #include <xsm/xsm.h>
 #include <xen/pmstat.h>
 #include <xen/gcov.h>
+#include <cpufreq/cpufreq.h>
 
 long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
 {
@@ -362,6 +363,13 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         break;
 #endif
 
+#ifdef HAS_XEN_CPUFREQ
+    case XEN_SYSCTL_cpufreq_op:
+        ret = sysctl_cpufreq_op(&op->u.cpufreq_op);
+	copyback = 1;
+        break;
+#endif
+
     default:
         ret = arch_do_sysctl(op, u_sysctl);
         copyback = 0;
diff --git a/xen/drivers/cpufreq/xen-cpufreq.c b/xen/drivers/cpufreq/xen-cpufreq.c
index 854955b..9b5d03f 100644
--- a/xen/drivers/cpufreq/xen-cpufreq.c
+++ b/xen/drivers/cpufreq/xen-cpufreq.c
@@ -50,6 +50,32 @@ static void notify_cpufreq_domains(void)
     send_global_virq(VIRQ_CPUFREQ);
 }
 
+int sysctl_cpufreq_op(xen_sysctl_cpufreq_op_t *op)
+{
+    int ret = 0;
+    switch ( op->cmd )
+    {
+    case XEN_SYSCTL_CPUFREQ_get_target:
+        spin_lock(&sysctl_cpufreq_lock);
+        op->u.target.cpu = sysctl_cpufreq_data.cpu;
+        op->u.target.freq = sysctl_cpufreq_data.freq;
+        op->u.target.relation = sysctl_cpufreq_data.relation;
+        spin_unlock(&sysctl_cpufreq_lock);
+        break;
+
+    case XEN_SYSCTL_CPUFREQ_set_result:
+        spin_lock(&sysctl_cpufreq_lock);
+	sysctl_cpufreq_data.result = op->u.result;
+        spin_unlock(&sysctl_cpufreq_lock);
+        break;
+
+    default:
+        return -ENOSYS;
+        break;
+    }
+    return ret;
+}
+
 static int xen_cpufreq_verify(struct cpufreq_policy *policy)
 {
     struct acpi_cpufreq_data *data;
diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
index 88ada16..cb68740 100644
--- a/xen/include/cpufreq/cpufreq.h
+++ b/xen/include/cpufreq/cpufreq.h
@@ -20,6 +20,7 @@
 #include <xen/spinlock.h>
 #include <xen/errno.h>
 #include <xen/cpumask.h>
+#include <public/sysctl.h>
 
 #include <cpufreq/processor_perf.h>
 
@@ -264,4 +265,8 @@ int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
 void cpufreq_dbs_timer_suspend(void);
 void cpufreq_dbs_timer_resume(void);
 
+#ifdef HAS_XEN_CPUFREQ
+int sysctl_cpufreq_op(xen_sysctl_cpufreq_op_t *op);
+#endif
+
 #endif /* __XEN_CPUFREQ_PM_H__ */
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 8437d31..ecd4674 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -632,6 +632,23 @@ struct xen_sysctl_coverage_op {
 typedef struct xen_sysctl_coverage_op xen_sysctl_coverage_op_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_coverage_op_t);
 
+#define XEN_SYSCTL_CPUFREQ_get_target      0
+#define XEN_SYSCTL_CPUFREQ_set_result      1
+
+struct xen_sysctl_cpufreq_op {
+    uint32_t cmd;
+    union {
+        struct {
+            uint32_t cpu;
+            uint32_t freq;
+            uint32_t relation;
+        } target;
+        uint32_t result;
+    } u;
+};
+typedef struct xen_sysctl_cpufreq_op xen_sysctl_cpufreq_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpufreq_op_t);
+
 
 struct xen_sysctl {
     uint32_t cmd;
@@ -654,6 +671,7 @@ struct xen_sysctl {
 #define XEN_SYSCTL_cpupool_op                    18
 #define XEN_SYSCTL_scheduler_op                  19
 #define XEN_SYSCTL_coverage_op                   20
+#define XEN_SYSCTL_cpufreq_op                    21
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
     union {
         struct xen_sysctl_readconsole       readconsole;
@@ -675,6 +693,7 @@ struct xen_sysctl {
         struct xen_sysctl_cpupool_op        cpupool_op;
         struct xen_sysctl_scheduler_op      scheduler_op;
         struct xen_sysctl_coverage_op       coverage_op;
+        struct xen_sysctl_cpufreq_op        cpufreq_op;
         uint8_t                             pad[128];
     } u;
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 13/13] xen/arm: enable cpufreq functionality for ARM
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (11 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 12/13] xen: arm: implement XEN_SYSCTL_cpufreq_op Oleksandr Dmytryshyn
@ 2014-10-07 14:19 ` Oleksandr Dmytryshyn
  2014-10-07 14:34 ` [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Jan Beulich
  13 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:19 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, Tim Deegan, xen-devel

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
---
 xen/arch/arm/Rules.mk | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk
index 718cd8a..caee255 100644
--- a/xen/arch/arm/Rules.mk
+++ b/xen/arch/arm/Rules.mk
@@ -9,6 +9,9 @@
 HAS_DEVICE_TREE := y
 HAS_VIDEO := y
 HAS_ARM_HDLCD := y
+HAS_CPUFREQ := y
+HAS_XEN_CPUFREQ := y
+HAS_PM := y
 
 CFLAGS += -I$(BASEDIR)/include
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
@ 2014-10-07 14:22   ` Andrew Cooper
  2014-10-07 14:27     ` Oleksandr Dmytryshyn
  2014-10-07 14:35   ` Jan Beulich
  1 sibling, 1 reply; 69+ messages in thread
From: Andrew Cooper @ 2014-10-07 14:22 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn, Ian Campbell, Stefano Stabellini,
	Tim Deegan, xen-devel

On 07/10/14 15:19, Oleksandr Dmytryshyn wrote:
> Cpufreq driver should be more generalizable (not ACPI-specific).
> Thus this file should be placed to the proper location.
>
> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>

In the future, please prepare patch series with the -M option which will
detect the move of cpufreq.h as a rename, and vastly reduce the size of
the patches.

~Andrew

> ---
>  xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
>  xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
>  xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
>  xen/arch/x86/acpi/power.c                    |   2 +-
>  xen/arch/x86/cpu/mwait-idle.c                |   2 +-
>  xen/drivers/acpi/pmstat.c                    |   2 +-
>  xen/drivers/cpufreq/cpufreq.c                |   2 +-
>  xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
>  xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
>  xen/drivers/cpufreq/utility.c                |   2 +-
>  xen/include/acpi/cpufreq/cpufreq.h           | 258 --------------------------
>  xen/include/cpufreq/cpufreq.h                | 261 +++++++++++++++++++++++++++
>  12 files changed, 272 insertions(+), 269 deletions(-)
>  delete mode 100644 xen/include/acpi/cpufreq/cpufreq.h
>  create mode 100644 xen/include/cpufreq/cpufreq.h
>
> diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
> index 597befa..98726ad 100644
> --- a/xen/arch/x86/acpi/cpu_idle.c
> +++ b/xen/arch/x86/acpi/cpu_idle.c
> @@ -51,7 +51,7 @@
>  #include <xen/softirq.h>
>  #include <public/platform.h>
>  #include <public/sysctl.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  #include <asm/apic.h>
>  #include <asm/cpuidle.h>
>  #include <asm/mwait.h>
> diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c
> index 4a6aeb3..4569d49 100644
> --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
> +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
> @@ -42,7 +42,7 @@
>  #include <asm/percpu.h>
>  #include <asm/cpufeature.h>
>  #include <acpi/acpi.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  enum {
>      UNDEFINED_CAPABLE = 0,
> diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c
> index 2c9fea2..0462e31 100644
> --- a/xen/arch/x86/acpi/cpufreq/powernow.c
> +++ b/xen/arch/x86/acpi/cpufreq/powernow.c
> @@ -36,7 +36,7 @@
>  #include <asm/percpu.h>
>  #include <asm/cpufeature.h>
>  #include <acpi/acpi.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  #define CPUID_6_ECX_APERFMPERF_CAPABILITY       (0x1)
>  #define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
> diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
> index f41f0de..d139e96 100644
> --- a/xen/arch/x86/acpi/power.c
> +++ b/xen/arch/x86/acpi/power.c
> @@ -29,7 +29,7 @@
>  #include <asm/tboot.h>
>  #include <asm/apic.h>
>  #include <asm/io_apic.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  uint32_t system_reset_counter = 1;
>  
> diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
> index 85179f2..a00c19a 100644
> --- a/xen/arch/x86/cpu/mwait-idle.c
> +++ b/xen/arch/x86/cpu/mwait-idle.c
> @@ -59,7 +59,7 @@
>  #include <asm/hpet.h>
>  #include <asm/mwait.h>
>  #include <asm/msr.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  #define MWAIT_IDLE_VERSION "0.4"
>  #undef PREFIX
> diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
> index daac2da..bd6ca43 100644
> --- a/xen/drivers/acpi/pmstat.c
> +++ b/xen/drivers/acpi/pmstat.c
> @@ -40,7 +40,7 @@
>  #include <xen/acpi.h>
>  
>  #include <public/sysctl.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  #include <xen/pmstat.h>
>  
>  DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
> diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
> index ab66884..884d2bb 100644
> --- a/xen/drivers/cpufreq/cpufreq.c
> +++ b/xen/drivers/cpufreq/cpufreq.c
> @@ -44,7 +44,7 @@
>  #include <asm/processor.h>
>  #include <asm/percpu.h>
>  #include <acpi/acpi.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  static unsigned int __read_mostly usr_min_freq;
>  static unsigned int __read_mostly usr_max_freq;
> diff --git a/xen/drivers/cpufreq/cpufreq_misc_governors.c b/xen/drivers/cpufreq/cpufreq_misc_governors.c
> index 746bbcd..881e4bb 100644
> --- a/xen/drivers/cpufreq/cpufreq_misc_governors.c
> +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c
> @@ -18,7 +18,7 @@
>  #include <xen/init.h>
>  #include <xen/percpu.h>
>  #include <xen/sched.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  /*
>   * cpufreq userspace governor
> diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
> index 7fdba03..f299116 100644
> --- a/xen/drivers/cpufreq/cpufreq_ondemand.c
> +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
> @@ -1,5 +1,5 @@
>  /*
> - *  xen/arch/x86/acpi/cpufreq/cpufreq_ondemand.c
> + *  xen/drivers/cpufreq/cpufreq_ondemand.c
>   *
>   *  Copyright (C)  2001 Russell King
>   *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
> @@ -18,7 +18,7 @@
>  #include <xen/types.h>
>  #include <xen/sched.h>
>  #include <xen/timer.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  
>  #define DEF_FREQUENCY_UP_THRESHOLD              (80)
>  #define MIN_FREQUENCY_UP_THRESHOLD              (11)
> diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c
> index 519f862..c9150a1 100644
> --- a/xen/drivers/cpufreq/utility.c
> +++ b/xen/drivers/cpufreq/utility.c
> @@ -28,7 +28,7 @@
>  #include <xen/sched.h>
>  #include <xen/timer.h>
>  #include <xen/trace.h>
> -#include <acpi/cpufreq/cpufreq.h>
> +#include <cpufreq/cpufreq.h>
>  #include <public/sysctl.h>
>  
>  struct cpufreq_driver   *cpufreq_driver;
> diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h
> deleted file mode 100644
> index f96c3e4..0000000
> --- a/xen/include/acpi/cpufreq/cpufreq.h
> +++ /dev/null
> @@ -1,258 +0,0 @@
> -/*
> - *  xen/include/acpi/cpufreq/cpufreq.h
> - *
> - *  Copyright (C) 2001 Russell King
> - *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
> - *
> - * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#ifndef __XEN_CPUFREQ_PM_H__
> -#define __XEN_CPUFREQ_PM_H__
> -
> -#include <xen/types.h>
> -#include <xen/list.h>
> -#include <xen/cpumask.h>
> -
> -#include "processor_perf.h"
> -
> -DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
> -
> -extern bool_t cpufreq_verbose;
> -
> -struct cpufreq_governor;
> -
> -struct acpi_cpufreq_data {
> -    struct processor_performance *acpi_data;
> -    struct cpufreq_frequency_table *freq_table;
> -    unsigned int arch_cpu_flags;
> -};
> -
> -extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
> -
> -struct cpufreq_cpuinfo {
> -    unsigned int        max_freq;
> -    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
> -    unsigned int        min_freq;
> -    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
> -};
> -
> -struct cpufreq_policy {
> -    cpumask_var_t       cpus;          /* affected CPUs */
> -    unsigned int        shared_type;   /* ANY or ALL affected CPUs
> -                                          should set cpufreq */
> -    unsigned int        cpu;           /* cpu nr of registered CPU */
> -    struct cpufreq_cpuinfo    cpuinfo;
> -
> -    unsigned int        min;    /* in kHz */
> -    unsigned int        max;    /* in kHz */
> -    unsigned int        cur;    /* in kHz, only needed if cpufreq
> -                                 * governors are used */
> -    struct cpufreq_governor     *governor;
> -
> -    bool_t              resume; /* flag for cpufreq 1st run
> -                                 * S3 wakeup, hotplug cpu, etc */
> -    s8                  turbo;  /* tristate flag: 0 for unsupported
> -                                 * -1 for disable, 1 for enabled
> -                                 * See CPUFREQ_TURBO_* below for defines */
> -    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
> -};
> -DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
> -
> -extern int __cpufreq_set_policy(struct cpufreq_policy *data,
> -                                struct cpufreq_policy *policy);
> -
> -void cpufreq_cmdline_parse(char *);
> -
> -#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
> -#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
> -#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
> -#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
> -
> -/******************** cpufreq transition notifiers *******************/
> -
> -struct cpufreq_freqs {
> -    unsigned int cpu;    /* cpu nr */
> -    unsigned int old;
> -    unsigned int new;
> -    u8 flags;            /* flags of cpufreq_driver, see below. */
> -};
> -
> -
> -/*********************************************************************
> - *                          CPUFREQ GOVERNORS                        *
> - *********************************************************************/
> -
> -#define CPUFREQ_GOV_START  1
> -#define CPUFREQ_GOV_STOP   2
> -#define CPUFREQ_GOV_LIMITS 3
> -
> -struct cpufreq_governor {
> -    char    name[CPUFREQ_NAME_LEN];
> -    int     (*governor)(struct cpufreq_policy *policy,
> -                        unsigned int event);
> -    bool_t  (*handle_option)(const char *name, const char *value);
> -    struct list_head governor_list;
> -};
> -
> -extern struct cpufreq_governor *cpufreq_opt_governor;
> -extern struct cpufreq_governor cpufreq_gov_dbs;
> -extern struct cpufreq_governor cpufreq_gov_userspace;
> -extern struct cpufreq_governor cpufreq_gov_performance;
> -extern struct cpufreq_governor cpufreq_gov_powersave;
> -
> -extern struct list_head cpufreq_governor_list;
> -
> -extern int cpufreq_register_governor(struct cpufreq_governor *governor);
> -extern struct cpufreq_governor *__find_governor(const char *governor);
> -#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
> -
> -/* pass a target to the cpufreq driver */
> -extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
> -                                   unsigned int target_freq,
> -                                   unsigned int relation);
> -
> -#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 int cpufreq_update_turbo(int cpuid, int new_state);
> -extern int cpufreq_get_turbo_status(int cpuid);
> -
> -static __inline__ int 
> -__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
> -{
> -    return policy->governor->governor(policy, event);
> -}
> -
> -
> -/*********************************************************************
> - *                      CPUFREQ DRIVER INTERFACE                     *
> - *********************************************************************/
> -
> -#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
> -#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
> -
> -struct cpufreq_driver {
> -    char   name[CPUFREQ_NAME_LEN];
> -    int    (*init)(struct cpufreq_policy *policy);
> -    int    (*verify)(struct cpufreq_policy *policy);
> -    int    (*update)(int cpuid, struct cpufreq_policy *policy);
> -    int    (*target)(struct cpufreq_policy *policy,
> -                     unsigned int target_freq,
> -                     unsigned int relation);
> -    unsigned int    (*get)(unsigned int cpu);
> -    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
> -    int    (*exit)(struct cpufreq_policy *policy);
> -};
> -
> -extern struct cpufreq_driver *cpufreq_driver;
> -
> -static __inline__ 
> -int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> -{
> -    if (!driver_data         || 
> -        !driver_data->init   || 
> -        !driver_data->exit   || 
> -        !driver_data->verify || 
> -        !driver_data->target)
> -        return -EINVAL;
> -
> -    if (cpufreq_driver)
> -        return -EBUSY;
> -
> -    cpufreq_driver = driver_data;
> -    return 0;
> -}
> -
> -static __inline__ 
> -int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> -{
> -    if (!cpufreq_driver || (driver != cpufreq_driver))
> -        return -EINVAL;
> -
> -    cpufreq_driver = NULL;
> -    return 0;
> -}
> -
> -static __inline__
> -void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
> -                                  unsigned int min, unsigned int max)
> -{
> -    if (policy->min < min)
> -        policy->min = min;
> -    if (policy->max < min)
> -        policy->max = min;
> -    if (policy->min > max)
> -        policy->min = max;
> -    if (policy->max > max)
> -        policy->max = max;
> -    if (policy->min > policy->max)
> -        policy->min = policy->max;
> -    return;
> -}
> -
> -
> -/*********************************************************************
> - *                     FREQUENCY TABLE HELPERS                       *
> - *********************************************************************/
> -
> -#define CPUFREQ_ENTRY_INVALID ~0
> -#define CPUFREQ_TABLE_END     ~1
> -
> -struct cpufreq_frequency_table {
> -    unsigned int    index;     /* any */
> -    unsigned int    frequency; /* kHz - doesn't need to be in ascending
> -                                * order */
> -};
> -
> -int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
> -                   struct cpufreq_frequency_table *table);
> -
> -int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
> -                   struct cpufreq_frequency_table *table);
> -
> -int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
> -                   struct cpufreq_frequency_table *table,
> -                   unsigned int target_freq,
> -                   unsigned int relation,
> -                   unsigned int *index);
> -
> -
> -/*********************************************************************
> - *                     UNIFIED DEBUG HELPERS                         *
> - *********************************************************************/
> -
> -struct cpu_dbs_info_s {
> -    uint64_t prev_cpu_idle;
> -    uint64_t prev_cpu_wall;
> -    struct cpufreq_policy *cur_policy;
> -    struct cpufreq_frequency_table *freq_table;
> -    int cpu;
> -    unsigned int enable:1;
> -    unsigned int stoppable:1;
> -    unsigned int turbo_enabled:1;
> -};
> -
> -int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
> -int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
> -                              uint32_t *sampling_rate_min,
> -                              uint32_t *sampling_rate,
> -                              uint32_t *up_threshold);
> -int write_ondemand_sampling_rate(unsigned int sampling_rate);
> -int write_ondemand_up_threshold(unsigned int up_threshold);
> -
> -int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
> -
> -void cpufreq_dbs_timer_suspend(void);
> -void cpufreq_dbs_timer_resume(void);
> -
> -#endif /* __XEN_CPUFREQ_PM_H__ */
> diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
> new file mode 100644
> index 0000000..04716f9
> --- /dev/null
> +++ b/xen/include/cpufreq/cpufreq.h
> @@ -0,0 +1,261 @@
> +/*
> + *  xen/include/cpufreq/cpufreq.h
> + *
> + *  Copyright (C) 2001 Russell King
> + *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
> + *
> + * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __XEN_CPUFREQ_PM_H__
> +#define __XEN_CPUFREQ_PM_H__
> +
> +#include <xen/types.h>
> +#include <xen/list.h>
> +#include <xen/percpu.h>
> +#include <xen/spinlock.h>
> +#include <xen/errno.h>
> +#include <xen/cpumask.h>
> +
> +#include <acpi/cpufreq/processor_perf.h>
> +
> +DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
> +
> +extern bool_t cpufreq_verbose;
> +
> +struct cpufreq_governor;
> +
> +struct acpi_cpufreq_data {
> +    struct processor_performance *acpi_data;
> +    struct cpufreq_frequency_table *freq_table;
> +    unsigned int arch_cpu_flags;
> +};
> +
> +extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
> +
> +struct cpufreq_cpuinfo {
> +    unsigned int        max_freq;
> +    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
> +    unsigned int        min_freq;
> +    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
> +};
> +
> +struct cpufreq_policy {
> +    cpumask_var_t       cpus;          /* affected CPUs */
> +    unsigned int        shared_type;   /* ANY or ALL affected CPUs
> +                                          should set cpufreq */
> +    unsigned int        cpu;           /* cpu nr of registered CPU */
> +    struct cpufreq_cpuinfo    cpuinfo;
> +
> +    unsigned int        min;    /* in kHz */
> +    unsigned int        max;    /* in kHz */
> +    unsigned int        cur;    /* in kHz, only needed if cpufreq
> +                                 * governors are used */
> +    struct cpufreq_governor     *governor;
> +
> +    bool_t              resume; /* flag for cpufreq 1st run
> +                                 * S3 wakeup, hotplug cpu, etc */
> +    s8                  turbo;  /* tristate flag: 0 for unsupported
> +                                 * -1 for disable, 1 for enabled
> +                                 * See CPUFREQ_TURBO_* below for defines */
> +    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
> +};
> +DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
> +
> +extern int __cpufreq_set_policy(struct cpufreq_policy *data,
> +                                struct cpufreq_policy *policy);
> +
> +void cpufreq_cmdline_parse(char *);
> +
> +#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
> +#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
> +#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
> +#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
> +
> +/******************** cpufreq transition notifiers *******************/
> +
> +struct cpufreq_freqs {
> +    unsigned int cpu;    /* cpu nr */
> +    unsigned int old;
> +    unsigned int new;
> +    u8 flags;            /* flags of cpufreq_driver, see below. */
> +};
> +
> +
> +/*********************************************************************
> + *                          CPUFREQ GOVERNORS                        *
> + *********************************************************************/
> +
> +#define CPUFREQ_GOV_START  1
> +#define CPUFREQ_GOV_STOP   2
> +#define CPUFREQ_GOV_LIMITS 3
> +
> +struct cpufreq_governor {
> +    char    name[CPUFREQ_NAME_LEN];
> +    int     (*governor)(struct cpufreq_policy *policy,
> +                        unsigned int event);
> +    bool_t  (*handle_option)(const char *name, const char *value);
> +    struct list_head governor_list;
> +};
> +
> +extern struct cpufreq_governor *cpufreq_opt_governor;
> +extern struct cpufreq_governor cpufreq_gov_dbs;
> +extern struct cpufreq_governor cpufreq_gov_userspace;
> +extern struct cpufreq_governor cpufreq_gov_performance;
> +extern struct cpufreq_governor cpufreq_gov_powersave;
> +
> +extern struct list_head cpufreq_governor_list;
> +
> +extern int cpufreq_register_governor(struct cpufreq_governor *governor);
> +extern struct cpufreq_governor *__find_governor(const char *governor);
> +#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
> +
> +/* pass a target to the cpufreq driver */
> +extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
> +                                   unsigned int target_freq,
> +                                   unsigned int relation);
> +
> +#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 int cpufreq_update_turbo(int cpuid, int new_state);
> +extern int cpufreq_get_turbo_status(int cpuid);
> +
> +static __inline__ int 
> +__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
> +{
> +    return policy->governor->governor(policy, event);
> +}
> +
> +
> +/*********************************************************************
> + *                      CPUFREQ DRIVER INTERFACE                     *
> + *********************************************************************/
> +
> +#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
> +#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
> +
> +struct cpufreq_driver {
> +    char   name[CPUFREQ_NAME_LEN];
> +    int    (*init)(struct cpufreq_policy *policy);
> +    int    (*verify)(struct cpufreq_policy *policy);
> +    int    (*update)(int cpuid, struct cpufreq_policy *policy);
> +    int    (*target)(struct cpufreq_policy *policy,
> +                     unsigned int target_freq,
> +                     unsigned int relation);
> +    unsigned int    (*get)(unsigned int cpu);
> +    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
> +    int    (*exit)(struct cpufreq_policy *policy);
> +};
> +
> +extern struct cpufreq_driver *cpufreq_driver;
> +
> +static __inline__ 
> +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> +{
> +    if (!driver_data         || 
> +        !driver_data->init   || 
> +        !driver_data->exit   || 
> +        !driver_data->verify || 
> +        !driver_data->target)
> +        return -EINVAL;
> +
> +    if (cpufreq_driver)
> +        return -EBUSY;
> +
> +    cpufreq_driver = driver_data;
> +    return 0;
> +}
> +
> +static __inline__ 
> +int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> +{
> +    if (!cpufreq_driver || (driver != cpufreq_driver))
> +        return -EINVAL;
> +
> +    cpufreq_driver = NULL;
> +    return 0;
> +}
> +
> +static __inline__
> +void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
> +                                  unsigned int min, unsigned int max)
> +{
> +    if (policy->min < min)
> +        policy->min = min;
> +    if (policy->max < min)
> +        policy->max = min;
> +    if (policy->min > max)
> +        policy->min = max;
> +    if (policy->max > max)
> +        policy->max = max;
> +    if (policy->min > policy->max)
> +        policy->min = policy->max;
> +    return;
> +}
> +
> +
> +/*********************************************************************
> + *                     FREQUENCY TABLE HELPERS                       *
> + *********************************************************************/
> +
> +#define CPUFREQ_ENTRY_INVALID ~0
> +#define CPUFREQ_TABLE_END     ~1
> +
> +struct cpufreq_frequency_table {
> +    unsigned int    index;     /* any */
> +    unsigned int    frequency; /* kHz - doesn't need to be in ascending
> +                                * order */
> +};
> +
> +int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
> +                   struct cpufreq_frequency_table *table);
> +
> +int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
> +                   struct cpufreq_frequency_table *table);
> +
> +int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
> +                   struct cpufreq_frequency_table *table,
> +                   unsigned int target_freq,
> +                   unsigned int relation,
> +                   unsigned int *index);
> +
> +
> +/*********************************************************************
> + *                     UNIFIED DEBUG HELPERS                         *
> + *********************************************************************/
> +
> +struct cpu_dbs_info_s {
> +    uint64_t prev_cpu_idle;
> +    uint64_t prev_cpu_wall;
> +    struct cpufreq_policy *cur_policy;
> +    struct cpufreq_frequency_table *freq_table;
> +    int cpu;
> +    unsigned int enable:1;
> +    unsigned int stoppable:1;
> +    unsigned int turbo_enabled:1;
> +};
> +
> +int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
> +int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
> +                              uint32_t *sampling_rate_min,
> +                              uint32_t *sampling_rate,
> +                              uint32_t *up_threshold);
> +int write_ondemand_sampling_rate(unsigned int sampling_rate);
> +int write_ondemand_up_threshold(unsigned int up_threshold);
> +
> +int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
> +
> +void cpufreq_dbs_timer_suspend(void);
> +void cpufreq_dbs_timer_resume(void);
> +
> +#endif /* __XEN_CPUFREQ_PM_H__ */

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  2014-10-07 14:22   ` Andrew Cooper
@ 2014-10-07 14:27     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-07 14:27 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:22 PM, Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>
> On 07/10/14 15:19, Oleksandr Dmytryshyn wrote:
> > Cpufreq driver should be more generalizable (not ACPI-specific).
> > Thus this file should be placed to the proper location.
> >
> > Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>
> In the future, please prepare patch series with the -M option which will
> detect the move of cpufreq.h as a rename, and vastly reduce the size of
> the patches.
I'll do this.

>
> ~Andrew
>
> > ---
> >  xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
> >  xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
> >  xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
> >  xen/arch/x86/acpi/power.c                    |   2 +-
> >  xen/arch/x86/cpu/mwait-idle.c                |   2 +-
> >  xen/drivers/acpi/pmstat.c                    |   2 +-
> >  xen/drivers/cpufreq/cpufreq.c                |   2 +-
> >  xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
> >  xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
> >  xen/drivers/cpufreq/utility.c                |   2 +-
> >  xen/include/acpi/cpufreq/cpufreq.h           | 258 --------------------------
> >  xen/include/cpufreq/cpufreq.h                | 261 +++++++++++++++++++++++++++
> >  12 files changed, 272 insertions(+), 269 deletions(-)
> >  delete mode 100644 xen/include/acpi/cpufreq/cpufreq.h
> >  create mode 100644 xen/include/cpufreq/cpufreq.h
> >
> > diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
> > index 597befa..98726ad 100644
> > --- a/xen/arch/x86/acpi/cpu_idle.c
> > +++ b/xen/arch/x86/acpi/cpu_idle.c
> > @@ -51,7 +51,7 @@
> >  #include <xen/softirq.h>
> >  #include <public/platform.h>
> >  #include <public/sysctl.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >  #include <asm/apic.h>
> >  #include <asm/cpuidle.h>
> >  #include <asm/mwait.h>
> > diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c
> > index 4a6aeb3..4569d49 100644
> > --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
> > +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
> > @@ -42,7 +42,7 @@
> >  #include <asm/percpu.h>
> >  #include <asm/cpufeature.h>
> >  #include <acpi/acpi.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  enum {
> >      UNDEFINED_CAPABLE = 0,
> > diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c
> > index 2c9fea2..0462e31 100644
> > --- a/xen/arch/x86/acpi/cpufreq/powernow.c
> > +++ b/xen/arch/x86/acpi/cpufreq/powernow.c
> > @@ -36,7 +36,7 @@
> >  #include <asm/percpu.h>
> >  #include <asm/cpufeature.h>
> >  #include <acpi/acpi.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  #define CPUID_6_ECX_APERFMPERF_CAPABILITY       (0x1)
> >  #define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
> > diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
> > index f41f0de..d139e96 100644
> > --- a/xen/arch/x86/acpi/power.c
> > +++ b/xen/arch/x86/acpi/power.c
> > @@ -29,7 +29,7 @@
> >  #include <asm/tboot.h>
> >  #include <asm/apic.h>
> >  #include <asm/io_apic.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  uint32_t system_reset_counter = 1;
> >
> > diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
> > index 85179f2..a00c19a 100644
> > --- a/xen/arch/x86/cpu/mwait-idle.c
> > +++ b/xen/arch/x86/cpu/mwait-idle.c
> > @@ -59,7 +59,7 @@
> >  #include <asm/hpet.h>
> >  #include <asm/mwait.h>
> >  #include <asm/msr.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  #define MWAIT_IDLE_VERSION "0.4"
> >  #undef PREFIX
> > diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
> > index daac2da..bd6ca43 100644
> > --- a/xen/drivers/acpi/pmstat.c
> > +++ b/xen/drivers/acpi/pmstat.c
> > @@ -40,7 +40,7 @@
> >  #include <xen/acpi.h>
> >
> >  #include <public/sysctl.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >  #include <xen/pmstat.h>
> >
> >  DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
> > diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
> > index ab66884..884d2bb 100644
> > --- a/xen/drivers/cpufreq/cpufreq.c
> > +++ b/xen/drivers/cpufreq/cpufreq.c
> > @@ -44,7 +44,7 @@
> >  #include <asm/processor.h>
> >  #include <asm/percpu.h>
> >  #include <acpi/acpi.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  static unsigned int __read_mostly usr_min_freq;
> >  static unsigned int __read_mostly usr_max_freq;
> > diff --git a/xen/drivers/cpufreq/cpufreq_misc_governors.c b/xen/drivers/cpufreq/cpufreq_misc_governors.c
> > index 746bbcd..881e4bb 100644
> > --- a/xen/drivers/cpufreq/cpufreq_misc_governors.c
> > +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c
> > @@ -18,7 +18,7 @@
> >  #include <xen/init.h>
> >  #include <xen/percpu.h>
> >  #include <xen/sched.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  /*
> >   * cpufreq userspace governor
> > diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
> > index 7fdba03..f299116 100644
> > --- a/xen/drivers/cpufreq/cpufreq_ondemand.c
> > +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
> > @@ -1,5 +1,5 @@
> >  /*
> > - *  xen/arch/x86/acpi/cpufreq/cpufreq_ondemand.c
> > + *  xen/drivers/cpufreq/cpufreq_ondemand.c
> >   *
> >   *  Copyright (C)  2001 Russell King
> >   *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
> > @@ -18,7 +18,7 @@
> >  #include <xen/types.h>
> >  #include <xen/sched.h>
> >  #include <xen/timer.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >
> >  #define DEF_FREQUENCY_UP_THRESHOLD              (80)
> >  #define MIN_FREQUENCY_UP_THRESHOLD              (11)
> > diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c
> > index 519f862..c9150a1 100644
> > --- a/xen/drivers/cpufreq/utility.c
> > +++ b/xen/drivers/cpufreq/utility.c
> > @@ -28,7 +28,7 @@
> >  #include <xen/sched.h>
> >  #include <xen/timer.h>
> >  #include <xen/trace.h>
> > -#include <acpi/cpufreq/cpufreq.h>
> > +#include <cpufreq/cpufreq.h>
> >  #include <public/sysctl.h>
> >
> >  struct cpufreq_driver   *cpufreq_driver;
> > diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h
> > deleted file mode 100644
> > index f96c3e4..0000000
> > --- a/xen/include/acpi/cpufreq/cpufreq.h
> > +++ /dev/null
> > @@ -1,258 +0,0 @@
> > -/*
> > - *  xen/include/acpi/cpufreq/cpufreq.h
> > - *
> > - *  Copyright (C) 2001 Russell King
> > - *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
> > - *
> > - * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
> > - *
> > - * This program is free software; you can redistribute it and/or modify
> > - * it under the terms of the GNU General Public License version 2 as
> > - * published by the Free Software Foundation.
> > - */
> > -
> > -#ifndef __XEN_CPUFREQ_PM_H__
> > -#define __XEN_CPUFREQ_PM_H__
> > -
> > -#include <xen/types.h>
> > -#include <xen/list.h>
> > -#include <xen/cpumask.h>
> > -
> > -#include "processor_perf.h"
> > -
> > -DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
> > -
> > -extern bool_t cpufreq_verbose;
> > -
> > -struct cpufreq_governor;
> > -
> > -struct acpi_cpufreq_data {
> > -    struct processor_performance *acpi_data;
> > -    struct cpufreq_frequency_table *freq_table;
> > -    unsigned int arch_cpu_flags;
> > -};
> > -
> > -extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
> > -
> > -struct cpufreq_cpuinfo {
> > -    unsigned int        max_freq;
> > -    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
> > -    unsigned int        min_freq;
> > -    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
> > -};
> > -
> > -struct cpufreq_policy {
> > -    cpumask_var_t       cpus;          /* affected CPUs */
> > -    unsigned int        shared_type;   /* ANY or ALL affected CPUs
> > -                                          should set cpufreq */
> > -    unsigned int        cpu;           /* cpu nr of registered CPU */
> > -    struct cpufreq_cpuinfo    cpuinfo;
> > -
> > -    unsigned int        min;    /* in kHz */
> > -    unsigned int        max;    /* in kHz */
> > -    unsigned int        cur;    /* in kHz, only needed if cpufreq
> > -                                 * governors are used */
> > -    struct cpufreq_governor     *governor;
> > -
> > -    bool_t              resume; /* flag for cpufreq 1st run
> > -                                 * S3 wakeup, hotplug cpu, etc */
> > -    s8                  turbo;  /* tristate flag: 0 for unsupported
> > -                                 * -1 for disable, 1 for enabled
> > -                                 * See CPUFREQ_TURBO_* below for defines */
> > -    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
> > -};
> > -DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
> > -
> > -extern int __cpufreq_set_policy(struct cpufreq_policy *data,
> > -                                struct cpufreq_policy *policy);
> > -
> > -void cpufreq_cmdline_parse(char *);
> > -
> > -#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
> > -#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
> > -#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
> > -#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
> > -
> > -/******************** cpufreq transition notifiers *******************/
> > -
> > -struct cpufreq_freqs {
> > -    unsigned int cpu;    /* cpu nr */
> > -    unsigned int old;
> > -    unsigned int new;
> > -    u8 flags;            /* flags of cpufreq_driver, see below. */
> > -};
> > -
> > -
> > -/*********************************************************************
> > - *                          CPUFREQ GOVERNORS                        *
> > - *********************************************************************/
> > -
> > -#define CPUFREQ_GOV_START  1
> > -#define CPUFREQ_GOV_STOP   2
> > -#define CPUFREQ_GOV_LIMITS 3
> > -
> > -struct cpufreq_governor {
> > -    char    name[CPUFREQ_NAME_LEN];
> > -    int     (*governor)(struct cpufreq_policy *policy,
> > -                        unsigned int event);
> > -    bool_t  (*handle_option)(const char *name, const char *value);
> > -    struct list_head governor_list;
> > -};
> > -
> > -extern struct cpufreq_governor *cpufreq_opt_governor;
> > -extern struct cpufreq_governor cpufreq_gov_dbs;
> > -extern struct cpufreq_governor cpufreq_gov_userspace;
> > -extern struct cpufreq_governor cpufreq_gov_performance;
> > -extern struct cpufreq_governor cpufreq_gov_powersave;
> > -
> > -extern struct list_head cpufreq_governor_list;
> > -
> > -extern int cpufreq_register_governor(struct cpufreq_governor *governor);
> > -extern struct cpufreq_governor *__find_governor(const char *governor);
> > -#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
> > -
> > -/* pass a target to the cpufreq driver */
> > -extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
> > -                                   unsigned int target_freq,
> > -                                   unsigned int relation);
> > -
> > -#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 int cpufreq_update_turbo(int cpuid, int new_state);
> > -extern int cpufreq_get_turbo_status(int cpuid);
> > -
> > -static __inline__ int
> > -__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
> > -{
> > -    return policy->governor->governor(policy, event);
> > -}
> > -
> > -
> > -/*********************************************************************
> > - *                      CPUFREQ DRIVER INTERFACE                     *
> > - *********************************************************************/
> > -
> > -#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
> > -#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
> > -
> > -struct cpufreq_driver {
> > -    char   name[CPUFREQ_NAME_LEN];
> > -    int    (*init)(struct cpufreq_policy *policy);
> > -    int    (*verify)(struct cpufreq_policy *policy);
> > -    int    (*update)(int cpuid, struct cpufreq_policy *policy);
> > -    int    (*target)(struct cpufreq_policy *policy,
> > -                     unsigned int target_freq,
> > -                     unsigned int relation);
> > -    unsigned int    (*get)(unsigned int cpu);
> > -    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
> > -    int    (*exit)(struct cpufreq_policy *policy);
> > -};
> > -
> > -extern struct cpufreq_driver *cpufreq_driver;
> > -
> > -static __inline__
> > -int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> > -{
> > -    if (!driver_data         ||
> > -        !driver_data->init   ||
> > -        !driver_data->exit   ||
> > -        !driver_data->verify ||
> > -        !driver_data->target)
> > -        return -EINVAL;
> > -
> > -    if (cpufreq_driver)
> > -        return -EBUSY;
> > -
> > -    cpufreq_driver = driver_data;
> > -    return 0;
> > -}
> > -
> > -static __inline__
> > -int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> > -{
> > -    if (!cpufreq_driver || (driver != cpufreq_driver))
> > -        return -EINVAL;
> > -
> > -    cpufreq_driver = NULL;
> > -    return 0;
> > -}
> > -
> > -static __inline__
> > -void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
> > -                                  unsigned int min, unsigned int max)
> > -{
> > -    if (policy->min < min)
> > -        policy->min = min;
> > -    if (policy->max < min)
> > -        policy->max = min;
> > -    if (policy->min > max)
> > -        policy->min = max;
> > -    if (policy->max > max)
> > -        policy->max = max;
> > -    if (policy->min > policy->max)
> > -        policy->min = policy->max;
> > -    return;
> > -}
> > -
> > -
> > -/*********************************************************************
> > - *                     FREQUENCY TABLE HELPERS                       *
> > - *********************************************************************/
> > -
> > -#define CPUFREQ_ENTRY_INVALID ~0
> > -#define CPUFREQ_TABLE_END     ~1
> > -
> > -struct cpufreq_frequency_table {
> > -    unsigned int    index;     /* any */
> > -    unsigned int    frequency; /* kHz - doesn't need to be in ascending
> > -                                * order */
> > -};
> > -
> > -int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
> > -                   struct cpufreq_frequency_table *table);
> > -
> > -int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
> > -                   struct cpufreq_frequency_table *table);
> > -
> > -int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
> > -                   struct cpufreq_frequency_table *table,
> > -                   unsigned int target_freq,
> > -                   unsigned int relation,
> > -                   unsigned int *index);
> > -
> > -
> > -/*********************************************************************
> > - *                     UNIFIED DEBUG HELPERS                         *
> > - *********************************************************************/
> > -
> > -struct cpu_dbs_info_s {
> > -    uint64_t prev_cpu_idle;
> > -    uint64_t prev_cpu_wall;
> > -    struct cpufreq_policy *cur_policy;
> > -    struct cpufreq_frequency_table *freq_table;
> > -    int cpu;
> > -    unsigned int enable:1;
> > -    unsigned int stoppable:1;
> > -    unsigned int turbo_enabled:1;
> > -};
> > -
> > -int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
> > -int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
> > -                              uint32_t *sampling_rate_min,
> > -                              uint32_t *sampling_rate,
> > -                              uint32_t *up_threshold);
> > -int write_ondemand_sampling_rate(unsigned int sampling_rate);
> > -int write_ondemand_up_threshold(unsigned int up_threshold);
> > -
> > -int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
> > -
> > -void cpufreq_dbs_timer_suspend(void);
> > -void cpufreq_dbs_timer_resume(void);
> > -
> > -#endif /* __XEN_CPUFREQ_PM_H__ */
> > diff --git a/xen/include/cpufreq/cpufreq.h b/xen/include/cpufreq/cpufreq.h
> > new file mode 100644
> > index 0000000..04716f9
> > --- /dev/null
> > +++ b/xen/include/cpufreq/cpufreq.h
> > @@ -0,0 +1,261 @@
> > +/*
> > + *  xen/include/cpufreq/cpufreq.h
> > + *
> > + *  Copyright (C) 2001 Russell King
> > + *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
> > + *
> > + * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#ifndef __XEN_CPUFREQ_PM_H__
> > +#define __XEN_CPUFREQ_PM_H__
> > +
> > +#include <xen/types.h>
> > +#include <xen/list.h>
> > +#include <xen/percpu.h>
> > +#include <xen/spinlock.h>
> > +#include <xen/errno.h>
> > +#include <xen/cpumask.h>
> > +
> > +#include <acpi/cpufreq/processor_perf.h>
> > +
> > +DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
> > +
> > +extern bool_t cpufreq_verbose;
> > +
> > +struct cpufreq_governor;
> > +
> > +struct acpi_cpufreq_data {
> > +    struct processor_performance *acpi_data;
> > +    struct cpufreq_frequency_table *freq_table;
> > +    unsigned int arch_cpu_flags;
> > +};
> > +
> > +extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
> > +
> > +struct cpufreq_cpuinfo {
> > +    unsigned int        max_freq;
> > +    unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
> > +    unsigned int        min_freq;
> > +    unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
> > +};
> > +
> > +struct cpufreq_policy {
> > +    cpumask_var_t       cpus;          /* affected CPUs */
> > +    unsigned int        shared_type;   /* ANY or ALL affected CPUs
> > +                                          should set cpufreq */
> > +    unsigned int        cpu;           /* cpu nr of registered CPU */
> > +    struct cpufreq_cpuinfo    cpuinfo;
> > +
> > +    unsigned int        min;    /* in kHz */
> > +    unsigned int        max;    /* in kHz */
> > +    unsigned int        cur;    /* in kHz, only needed if cpufreq
> > +                                 * governors are used */
> > +    struct cpufreq_governor     *governor;
> > +
> > +    bool_t              resume; /* flag for cpufreq 1st run
> > +                                 * S3 wakeup, hotplug cpu, etc */
> > +    s8                  turbo;  /* tristate flag: 0 for unsupported
> > +                                 * -1 for disable, 1 for enabled
> > +                                 * See CPUFREQ_TURBO_* below for defines */
> > +    bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
> > +};
> > +DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
> > +
> > +extern int __cpufreq_set_policy(struct cpufreq_policy *data,
> > +                                struct cpufreq_policy *policy);
> > +
> > +void cpufreq_cmdline_parse(char *);
> > +
> > +#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
> > +#define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
> > +#define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
> > +#define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
> > +
> > +/******************** cpufreq transition notifiers *******************/
> > +
> > +struct cpufreq_freqs {
> > +    unsigned int cpu;    /* cpu nr */
> > +    unsigned int old;
> > +    unsigned int new;
> > +    u8 flags;            /* flags of cpufreq_driver, see below. */
> > +};
> > +
> > +
> > +/*********************************************************************
> > + *                          CPUFREQ GOVERNORS                        *
> > + *********************************************************************/
> > +
> > +#define CPUFREQ_GOV_START  1
> > +#define CPUFREQ_GOV_STOP   2
> > +#define CPUFREQ_GOV_LIMITS 3
> > +
> > +struct cpufreq_governor {
> > +    char    name[CPUFREQ_NAME_LEN];
> > +    int     (*governor)(struct cpufreq_policy *policy,
> > +                        unsigned int event);
> > +    bool_t  (*handle_option)(const char *name, const char *value);
> > +    struct list_head governor_list;
> > +};
> > +
> > +extern struct cpufreq_governor *cpufreq_opt_governor;
> > +extern struct cpufreq_governor cpufreq_gov_dbs;
> > +extern struct cpufreq_governor cpufreq_gov_userspace;
> > +extern struct cpufreq_governor cpufreq_gov_performance;
> > +extern struct cpufreq_governor cpufreq_gov_powersave;
> > +
> > +extern struct list_head cpufreq_governor_list;
> > +
> > +extern int cpufreq_register_governor(struct cpufreq_governor *governor);
> > +extern struct cpufreq_governor *__find_governor(const char *governor);
> > +#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
> > +
> > +/* pass a target to the cpufreq driver */
> > +extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
> > +                                   unsigned int target_freq,
> > +                                   unsigned int relation);
> > +
> > +#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 int cpufreq_update_turbo(int cpuid, int new_state);
> > +extern int cpufreq_get_turbo_status(int cpuid);
> > +
> > +static __inline__ int
> > +__cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
> > +{
> > +    return policy->governor->governor(policy, event);
> > +}
> > +
> > +
> > +/*********************************************************************
> > + *                      CPUFREQ DRIVER INTERFACE                     *
> > + *********************************************************************/
> > +
> > +#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
> > +#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
> > +
> > +struct cpufreq_driver {
> > +    char   name[CPUFREQ_NAME_LEN];
> > +    int    (*init)(struct cpufreq_policy *policy);
> > +    int    (*verify)(struct cpufreq_policy *policy);
> > +    int    (*update)(int cpuid, struct cpufreq_policy *policy);
> > +    int    (*target)(struct cpufreq_policy *policy,
> > +                     unsigned int target_freq,
> > +                     unsigned int relation);
> > +    unsigned int    (*get)(unsigned int cpu);
> > +    unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
> > +    int    (*exit)(struct cpufreq_policy *policy);
> > +};
> > +
> > +extern struct cpufreq_driver *cpufreq_driver;
> > +
> > +static __inline__
> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> > +{
> > +    if (!driver_data         ||
> > +        !driver_data->init   ||
> > +        !driver_data->exit   ||
> > +        !driver_data->verify ||
> > +        !driver_data->target)
> > +        return -EINVAL;
> > +
> > +    if (cpufreq_driver)
> > +        return -EBUSY;
> > +
> > +    cpufreq_driver = driver_data;
> > +    return 0;
> > +}
> > +
> > +static __inline__
> > +int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> > +{
> > +    if (!cpufreq_driver || (driver != cpufreq_driver))
> > +        return -EINVAL;
> > +
> > +    cpufreq_driver = NULL;
> > +    return 0;
> > +}
> > +
> > +static __inline__
> > +void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
> > +                                  unsigned int min, unsigned int max)
> > +{
> > +    if (policy->min < min)
> > +        policy->min = min;
> > +    if (policy->max < min)
> > +        policy->max = min;
> > +    if (policy->min > max)
> > +        policy->min = max;
> > +    if (policy->max > max)
> > +        policy->max = max;
> > +    if (policy->min > policy->max)
> > +        policy->min = policy->max;
> > +    return;
> > +}
> > +
> > +
> > +/*********************************************************************
> > + *                     FREQUENCY TABLE HELPERS                       *
> > + *********************************************************************/
> > +
> > +#define CPUFREQ_ENTRY_INVALID ~0
> > +#define CPUFREQ_TABLE_END     ~1
> > +
> > +struct cpufreq_frequency_table {
> > +    unsigned int    index;     /* any */
> > +    unsigned int    frequency; /* kHz - doesn't need to be in ascending
> > +                                * order */
> > +};
> > +
> > +int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
> > +                   struct cpufreq_frequency_table *table);
> > +
> > +int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
> > +                   struct cpufreq_frequency_table *table);
> > +
> > +int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
> > +                   struct cpufreq_frequency_table *table,
> > +                   unsigned int target_freq,
> > +                   unsigned int relation,
> > +                   unsigned int *index);
> > +
> > +
> > +/*********************************************************************
> > + *                     UNIFIED DEBUG HELPERS                         *
> > + *********************************************************************/
> > +
> > +struct cpu_dbs_info_s {
> > +    uint64_t prev_cpu_idle;
> > +    uint64_t prev_cpu_wall;
> > +    struct cpufreq_policy *cur_policy;
> > +    struct cpufreq_frequency_table *freq_table;
> > +    int cpu;
> > +    unsigned int enable:1;
> > +    unsigned int stoppable:1;
> > +    unsigned int turbo_enabled:1;
> > +};
> > +
> > +int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
> > +int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
> > +                              uint32_t *sampling_rate_min,
> > +                              uint32_t *sampling_rate,
> > +                              uint32_t *up_threshold);
> > +int write_ondemand_sampling_rate(unsigned int sampling_rate);
> > +int write_ondemand_up_threshold(unsigned int up_threshold);
> > +
> > +int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
> > +
> > +void cpufreq_dbs_timer_suspend(void);
> > +void cpufreq_dbs_timer_resume(void);
> > +
> > +#endif /* __XEN_CPUFREQ_PM_H__ */
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor
  2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
                   ` (12 preceding siblings ...)
  2014-10-07 14:19 ` [RFC PATCH 13/13] xen/arm: enable cpufreq functionality for ARM Oleksandr Dmytryshyn
@ 2014-10-07 14:34 ` Jan Beulich
  13 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:34 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> Next series of patches implements xen-cpufreq driver in Xen hypervisor.

Very unfortunate timing I'm afraid. I'll take a brief look, but submitting
such patch sets outside of code freeze windows would be much
appreciated. That said - your Cc list seems to be incomplete (or really
it's empty, because you included a number of people explicitly on the
To line).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
  2014-10-07 14:22   ` Andrew Cooper
@ 2014-10-07 14:35   ` Jan Beulich
  2014-10-09  6:04     ` Oleksandr Dmytryshyn
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:35 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> Cpufreq driver should be more generalizable (not ACPI-specific).
> Thus this file should be placed to the proper location.

For an arbitrary definition of "proper", because ...

> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
> ---
>  xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
>  xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
>  xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
>  xen/arch/x86/acpi/power.c                    |   2 +-
>  xen/arch/x86/cpu/mwait-idle.c                |   2 +-
>  xen/drivers/acpi/pmstat.c                    |   2 +-
>  xen/drivers/cpufreq/cpufreq.c                |   2 +-
>  xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
>  xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
>  xen/drivers/cpufreq/utility.c                |   2 +-
>  xen/include/acpi/cpufreq/cpufreq.h           | 258 --------------------------
>  xen/include/cpufreq/cpufreq.h                | 261 +++++++++++++++++++++++++++

I have a hard time seeing why we'd need a cpufreq/ subdir here.
Just put this in include/xen/.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location
  2014-10-07 14:19 ` [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location Oleksandr Dmytryshyn
@ 2014-10-07 14:38   ` Jan Beulich
  2014-10-09  6:05     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:38 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> Cpufreq driver should be more generalizable (not ACPI-specific).
> Thus this file should be placed to the proper location.
> 
> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
> ---
>  xen/Rules.mk              |   1 +
>  xen/arch/x86/Rules.mk     |   1 +
>  xen/common/sysctl.c       |   2 +-
>  xen/drivers/Makefile      |   1 +
>  xen/drivers/acpi/Makefile |   1 -
>  xen/drivers/acpi/pmstat.c | 528 ----------------------------------------------
>  xen/drivers/pm/Makefile   |   1 +
>  xen/drivers/pm/pmstat.c   | 528 ++++++++++++++++++++++++++++++++++++++++++++++

xen/drivers/pm/stat.c would seem more suitable (if we really need a
pm/ subdir here in the first place).

Also, when you move files please make sure you update
./MAINTAINERS accordingly - in the case here the file would change
maintainership without you doing so.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture
  2014-10-07 14:19 ` [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture Oleksandr Dmytryshyn
@ 2014-10-07 14:39   ` Jan Beulich
  2014-10-09  6:05     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:39 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> This settings is x86-specific and should not be used for
> other architectures.

There's nothing iherently x86-specific here, so this should use a
CONFIG_/HAVE_/HAS_ abstraction just like other pieces do.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable
  2014-10-07 14:19 ` [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable Oleksandr Dmytryshyn
@ 2014-10-07 14:40   ` Jan Beulich
  2014-10-09  6:06     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:40 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> @@ -133,7 +132,8 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
>          cpufreq_statistic_reset(op->cpuid);
>          break;
>      }
> -
> +/* For now those operations are supported only for X86 */
> +#ifdef CONFIG_X86
>      case PMSTAT_get_max_cx:
>      {
>          op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);

So why is this not CONFIG_ACPI then?

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/13] cpufreq: make cpufreq driver more generalizable
  2014-10-07 14:19 ` [RFC PATCH 06/13] cpufreq: make cpufreq driver " Oleksandr Dmytryshyn
@ 2014-10-07 14:42   ` Jan Beulich
  2014-10-09  6:06     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:42 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> @@ -207,6 +213,18 @@ int cpufreq_add_cpu(unsigned int cpu)
>                  );
>              return -EINVAL;
>          }
> +#else /* CONFIG_ACPI */
> +        if ((perf->domain_info.num_processors !=
> +            processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
> +
> +            printk(KERN_WARNING "cpufreq fail to add CPU%d:"
> +                   "incorrect _PSD(%"PRIu64"), expect(%"PRIu64")\n",
> +                   cpu, perf->domain_info.num_processors,
> +                   processor_pminfo[firstcpu]->perf.domain_info.num_processors
> +                );
> +            return -EINVAL;
> +        }
> +#endif /* CONFIG_ACPI */

This seems rather arbitrary: What is _PSD outside of ACPI or a similar
spec? If you want to generalize the file, please truly do so.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-07 14:19 ` [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver Oleksandr Dmytryshyn
@ 2014-10-07 14:44   ` Jan Beulich
  2014-10-08 13:51     ` Stefano Stabellini
  2014-10-09  6:13     ` Oleksandr Dmytryshyn
  0 siblings, 2 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-07 14:44 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> This driver uses Dom0 to change frequencies on CPUs

In which case its name should be dom0-cpufreq. But I very much
question a model where it is not the hypervisor controlling aspects
of physical CPUs.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global
  2014-10-07 14:19 ` [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global Oleksandr Dmytryshyn
@ 2014-10-07 15:09   ` Julien Grall
  2014-10-09  6:09     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-10-07 15:09 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn, Ian Campbell, Stefano Stabellini,
	Tim Deegan, xen-devel

Hi Oleksandr,

On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
> This patch makes possible to use the dt_find_property function
> outside the device tree module.

I can't find any usage of this function within your series. Any reason
to export it?

Regards,

> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
> ---
>  xen/common/device_tree.c      | 2 +-
>  xen/include/xen/device_tree.h | 9 +++++++++
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index f0bd7b9..5fbb0c1 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -522,7 +522,7 @@ static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  }
>  
>  /* Find a property with a given name for a given node and return it. */
> -static const struct dt_property *
> +const struct dt_property *
>  dt_find_property(const struct dt_device_node *np,
>                   const char *name,
>                   u32 *lenp)
> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> index 99de53f..508d840 100644
> --- a/xen/include/xen/device_tree.h
> +++ b/xen/include/xen/device_tree.h
> @@ -344,6 +344,15 @@ struct dt_device_node *dt_find_compatible_node(struct dt_device_node *from,
>  
>  /**
>   * Find a property with a given name for a given node
> + * and return it.
> + */
> +const struct dt_property *dt_find_property(const struct dt_device_node *np,
> +                                           const char *name,
> +                                           u32 *lenp);
> +
> +
> +/**
> + * Find a property with a given name for a given node
>   * and return the value.
>   */
>  const void *dt_get_property(const struct dt_device_node *np,
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 07/13] xen/arm: enable cpu hotplug
  2014-10-07 14:19 ` [RFC PATCH 07/13] xen/arm: enable cpu hotplug Oleksandr Dmytryshyn
@ 2014-10-07 15:15   ` Julien Grall
  2014-10-09  6:07     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-10-07 15:15 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn, Ian Campbell, Stefano Stabellini,
	Tim Deegan, xen-devel

Hi Oleksandr,

On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
> This config is needed for the cpufreq driver.

Can you expand why your really need it? I don't find any usage of those
define except in:
	include/xen/cpumask.h
	include/xen/init.h

Technically, supporting CPU hotplug in Xen ARM will require more than
enabling those defines. I doubt the code is ready for CPU hotplugging
(for instance see setup_virt_paging).

Regards,

> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
> ---
>  xen/include/asm-arm/config.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
> index 5b7b1a8..ca17c79 100644
> --- a/xen/include/asm-arm/config.h
> +++ b/xen/include/asm-arm/config.h
> @@ -203,6 +203,9 @@ extern unsigned long frametable_virt_end;
>  #define GIC_VR_OFFSET 0x6000 /* Virtual Machine CPU interface) */
>  #endif /* __ASSEMBLY__ */
>  
> +#define CONFIG_HOTPLUG 1
> +#define CONFIG_HOTPLUG_CPU 1
> +
>  #endif /* __ARM_CONFIG_H__ */
>  /*
>   * Local variables:
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver
  2014-10-07 14:19 ` [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver Oleksandr Dmytryshyn
@ 2014-10-07 15:26   ` Julien Grall
  2014-10-09  6:10     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-10-07 15:26 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn, Ian Campbell, Stefano Stabellini,
	Tim Deegan, xen-devel

Hi Oleksandr,

On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
> This patch copies all cpu@0..cpu@N nodes (from input
> device tree) with properties to /cpus/cpu@0/private_data
> node (device tree for Dom0). Thus we can have any number
> of VCPUs in Dom0 and we give all information about all
> physical CPUs in the private_data node. Driver in Dom0
> should parse /cpus/cpu@0/private_data path instead of the
> /cpus path in the device tree.
> 
> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
> ---
>  xen/arch/arm/domain_build.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 2db0236..a142cc4 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -436,6 +436,10 @@ static int make_cpus_node(const struct domain *d, void *fdt,
>      char buf[15];
>      u32 clock_frequency;
>      bool_t clock_valid;
> +#ifdef HAS_CPUFREQ
> +    const struct dt_property *pp;
> +    char *node_name;
> +#endif
>  
>      DPRINT("Create cpus node\n");
>  
> @@ -517,6 +521,60 @@ static int make_cpus_node(const struct domain *d, void *fdt,
>                  return res;
>          }
>  

The function make_cpus_node is quite big. I would introduce a new
function to copy the "private_data".

I was also thinking if it wouldn't have been better to move those nodes
under the hypervisor one because it's Xen stuff.

> +#ifdef HAS_CPUFREQ
> +        /*
> +         * Add "private_data" node to cpu@0 and copy to it
> +         * original cpu@0..cpu@N nodes with its properties.
> +         * This is needed for the cpufreq cpu driver in Dom0
> +         */

This copy is mostly related to Xen
Wouldn't it be better to copy those nodes in the hypervisor node?

> +        if ( cpu == 0 )
> +        {
> +            DPRINT("Create private_data node\n");
> +
> +            res = fdt_begin_node(fdt, "private_data");
> +            if ( res )
> +                return res;
> +
> +            dt_for_each_child_node( cpus, npcpu )
> +            {
> +                if ( dt_device_type_is_equal(npcpu, "cpu") )
> +                {
> +                    node_name = strrchr(dt_node_full_name(npcpu), '/');
> +                    if ( node_name )
> +                        node_name++;

IIRC, it's not possible to have an empty node_name here. The node name
will always be /cpus/name.

I would turn this if to an ASSERT, and drop the if just below.

> +
> +                    if ( node_name && *node_name )
> +                    {

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 10/13] xen: arm: implement platform hypercall
  2014-10-07 14:19 ` [RFC PATCH 10/13] xen: arm: implement platform hypercall Oleksandr Dmytryshyn
@ 2014-10-07 15:39   ` Julien Grall
  2014-10-09  6:11     ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-10-07 15:39 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn, Ian Campbell, Stefano Stabellini,
	Tim Deegan, xen-devel

Hi Oleksandr,

On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
> +ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
> +{
> +    ret_t ret = 0;
> +    struct xen_platform_op curop, *op = &curop;
> +
> +    if ( copy_from_guest(op, u_xenpf_op, 1) )
> +        return -EFAULT;
> +
> +    if ( op->interface_version != XENPF_INTERFACE_VERSION )
> +        return -EACCES;

Why did you drop the XSM check here?

Overall, the skeleton of this function is very similar to the x86. I
would move the common part in xen/common and add arch implementation
when it's necessary. You can give a look to do_domctl and arch_do_domctl.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-07 14:44   ` Jan Beulich
@ 2014-10-08 13:51     ` Stefano Stabellini
  2014-10-10  9:00       ` Jan Beulich
  2014-10-10  9:39       ` Jan Beulich
  2014-10-09  6:13     ` Oleksandr Dmytryshyn
  1 sibling, 2 replies; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-08 13:51 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Tim Deegan, Oleksandr Dmytryshyn, Stefano Stabellini,
	Ian Campbell, xen-devel

On Tue, 7 Oct 2014, Jan Beulich wrote:
> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> > This driver uses Dom0 to change frequencies on CPUs
> 
> In which case its name should be dom0-cpufreq. But I very much
> question a model where it is not the hypervisor controlling aspects
> of physical CPUs.

Me too, however we had a long discussion (see
CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
Oleksandr and others thought that it would require too much drivers code
to change cpu frequency directly in Xen on ARM
(CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).

They might be right.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location
  2014-10-07 14:35   ` Jan Beulich
@ 2014-10-09  6:04     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:04 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:35 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> Cpufreq driver should be more generalizable (not ACPI-specific).
>> Thus this file should be placed to the proper location.
>
> For an arbitrary definition of "proper", because ...
>
>> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>> ---
>>  xen/arch/x86/acpi/cpu_idle.c                 |   2 +-
>>  xen/arch/x86/acpi/cpufreq/cpufreq.c          |   2 +-
>>  xen/arch/x86/acpi/cpufreq/powernow.c         |   2 +-
>>  xen/arch/x86/acpi/power.c                    |   2 +-
>>  xen/arch/x86/cpu/mwait-idle.c                |   2 +-
>>  xen/drivers/acpi/pmstat.c                    |   2 +-
>>  xen/drivers/cpufreq/cpufreq.c                |   2 +-
>>  xen/drivers/cpufreq/cpufreq_misc_governors.c |   2 +-
>>  xen/drivers/cpufreq/cpufreq_ondemand.c       |   4 +-
>>  xen/drivers/cpufreq/utility.c                |   2 +-
>>  xen/include/acpi/cpufreq/cpufreq.h           | 258 --------------------------
>>  xen/include/cpufreq/cpufreq.h                | 261 +++++++++++++++++++++++++++
>
> I have a hard time seeing why we'd need a cpufreq/ subdir here.
> Just put this in include/xen/.
I'll do it in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location
  2014-10-07 14:38   ` Jan Beulich
@ 2014-10-09  6:05     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:38 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> Cpufreq driver should be more generalizable (not ACPI-specific).
>> Thus this file should be placed to the proper location.
>>
>> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>> ---
>>  xen/Rules.mk              |   1 +
>>  xen/arch/x86/Rules.mk     |   1 +
>>  xen/common/sysctl.c       |   2 +-
>>  xen/drivers/Makefile      |   1 +
>>  xen/drivers/acpi/Makefile |   1 -
>>  xen/drivers/acpi/pmstat.c | 528 ----------------------------------------------
>>  xen/drivers/pm/Makefile   |   1 +
>>  xen/drivers/pm/pmstat.c   | 528 ++++++++++++++++++++++++++++++++++++++++++++++
>
> xen/drivers/pm/stat.c would seem more suitable (if we really need a
> pm/ subdir here in the first place).
>
> Also, when you move files please make sure you update
> ./MAINTAINERS accordingly - in the case here the file would change
> maintainership without you doing so.

I'll do it in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture
  2014-10-07 14:39   ` Jan Beulich
@ 2014-10-09  6:05     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:39 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> This settings is x86-specific and should not be used for
>> other architectures.
>
> There's nothing iherently x86-specific here, so this should use a
> CONFIG_/HAVE_/HAS_ abstraction just like other pieces do.
I'll do it in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable
  2014-10-07 14:40   ` Jan Beulich
@ 2014-10-09  6:06     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:40 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> @@ -133,7 +132,8 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
>>          cpufreq_statistic_reset(op->cpuid);
>>          break;
>>      }
>> -
>> +/* For now those operations are supported only for X86 */
>> +#ifdef CONFIG_X86
>>      case PMSTAT_get_max_cx:
>>      {
>>          op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
>
> So why is this not CONFIG_ACPI then?
I'll change CONFIG_X86 to the CONFIG_ACPI  in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/13] cpufreq: make cpufreq driver more generalizable
  2014-10-07 14:42   ` Jan Beulich
@ 2014-10-09  6:06     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:42 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> @@ -207,6 +213,18 @@ int cpufreq_add_cpu(unsigned int cpu)
>>                  );
>>              return -EINVAL;
>>          }
>> +#else /* CONFIG_ACPI */
>> +        if ((perf->domain_info.num_processors !=
>> +            processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
>> +
>> +            printk(KERN_WARNING "cpufreq fail to add CPU%d:"
>> +                   "incorrect _PSD(%"PRIu64"), expect(%"PRIu64")\n",
>> +                   cpu, perf->domain_info.num_processors,
>> +                   processor_pminfo[firstcpu]->perf.domain_info.num_processors
>> +                );
>> +            return -EINVAL;
>> +        }
>> +#endif /* CONFIG_ACPI */
>
> This seems rather arbitrary: What is _PSD outside of ACPI or a similar
> spec? If you want to generalize the file, please truly do so.
I'll do it in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 07/13] xen/arm: enable cpu hotplug
  2014-10-07 15:15   ` Julien Grall
@ 2014-10-09  6:07     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:07 UTC (permalink / raw)
  To: Julien Grall; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 6:15 PM, Julien Grall <julien.grall@linaro.org> wrote:
> Hi Oleksandr,
>
> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>> This config is needed for the cpufreq driver.
>
> Can you expand why your really need it? I don't find any usage of those
> define except in:
>         include/xen/cpumask.h
>         include/xen/init.h
>
> Technically, supporting CPU hotplug in Xen ARM will require more than
> enabling those defines. I doubt the code is ready for CPU hotplugging
> (for instance see setup_virt_paging).
I'll drop this patch.

> Regards,
>
>> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>> ---
>>  xen/include/asm-arm/config.h | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
>> index 5b7b1a8..ca17c79 100644
>> --- a/xen/include/asm-arm/config.h
>> +++ b/xen/include/asm-arm/config.h
>> @@ -203,6 +203,9 @@ extern unsigned long frametable_virt_end;
>>  #define GIC_VR_OFFSET 0x6000 /* Virtual Machine CPU interface) */
>>  #endif /* __ASSEMBLY__ */
>>
>> +#define CONFIG_HOTPLUG 1
>> +#define CONFIG_HOTPLUG_CPU 1
>> +
>>  #endif /* __ARM_CONFIG_H__ */
>>  /*
>>   * Local variables:
>>
>
>
> --
> Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global
  2014-10-07 15:09   ` Julien Grall
@ 2014-10-09  6:09     ` Oleksandr Dmytryshyn
  2014-10-09 11:15       ` Julien Grall
  0 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:09 UTC (permalink / raw)
  To: Julien Grall; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 6:09 PM, Julien Grall <julien.grall@linaro.org> wrote:
> Hi Oleksandr,
>
> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>> This patch makes possible to use the dt_find_property function
>> outside the device tree module.
>
> I can't find any usage of this function within your series. Any reason
> to export it?
This function is used by patch in this series
([RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq
cpu drive).

> Regards,
>
>> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>> ---
>>  xen/common/device_tree.c      | 2 +-
>>  xen/include/xen/device_tree.h | 9 +++++++++
>>  2 files changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
>> index f0bd7b9..5fbb0c1 100644
>> --- a/xen/common/device_tree.c
>> +++ b/xen/common/device_tree.c
>> @@ -522,7 +522,7 @@ static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>>  }
>>
>>  /* Find a property with a given name for a given node and return it. */
>> -static const struct dt_property *
>> +const struct dt_property *
>>  dt_find_property(const struct dt_device_node *np,
>>                   const char *name,
>>                   u32 *lenp)
>> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
>> index 99de53f..508d840 100644
>> --- a/xen/include/xen/device_tree.h
>> +++ b/xen/include/xen/device_tree.h
>> @@ -344,6 +344,15 @@ struct dt_device_node *dt_find_compatible_node(struct dt_device_node *from,
>>
>>  /**
>>   * Find a property with a given name for a given node
>> + * and return it.
>> + */
>> +const struct dt_property *dt_find_property(const struct dt_device_node *np,
>> +                                           const char *name,
>> +                                           u32 *lenp);
>> +
>> +
>> +/**
>> + * Find a property with a given name for a given node
>>   * and return the value.
>>   */
>>  const void *dt_get_property(const struct dt_device_node *np,
>>
>
>
> --
> Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver
  2014-10-07 15:26   ` Julien Grall
@ 2014-10-09  6:10     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:10 UTC (permalink / raw)
  To: Julien Grall; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 6:26 PM, Julien Grall <julien.grall@linaro.org> wrote:
> Hi Oleksandr,
>
> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>> This patch copies all cpu@0..cpu@N nodes (from input
>> device tree) with properties to /cpus/cpu@0/private_data
>> node (device tree for Dom0). Thus we can have any number
>> of VCPUs in Dom0 and we give all information about all
>> physical CPUs in the private_data node. Driver in Dom0
>> should parse /cpus/cpu@0/private_data path instead of the
>> /cpus path in the device tree.
>>
>> Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
>> ---
>>  xen/arch/arm/domain_build.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 58 insertions(+)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 2db0236..a142cc4 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -436,6 +436,10 @@ static int make_cpus_node(const struct domain *d, void *fdt,
>>      char buf[15];
>>      u32 clock_frequency;
>>      bool_t clock_valid;
>> +#ifdef HAS_CPUFREQ
>> +    const struct dt_property *pp;
>> +    char *node_name;
>> +#endif
>>
>>      DPRINT("Create cpus node\n");
>>
>> @@ -517,6 +521,60 @@ static int make_cpus_node(const struct domain *d, void *fdt,
>>                  return res;
>>          }
>>
>
> The function make_cpus_node is quite big. I would introduce a new
> function to copy the "private_data".
>
> I was also thinking if it wouldn't have been better to move those nodes
> under the hypervisor one because it's Xen stuff.
I'll do it in the next patch-set.

>> +#ifdef HAS_CPUFREQ
>> +        /*
>> +         * Add "private_data" node to cpu@0 and copy to it
>> +         * original cpu@0..cpu@N nodes with its properties.
>> +         * This is needed for the cpufreq cpu driver in Dom0
>> +         */
>
> This copy is mostly related to Xen
> Wouldn't it be better to copy those nodes in the hypervisor node?
I'll do it in the next patch-set.

>> +        if ( cpu == 0 )
>> +        {
>> +            DPRINT("Create private_data node\n");
>> +
>> +            res = fdt_begin_node(fdt, "private_data");
>> +            if ( res )
>> +                return res;
>> +
>> +            dt_for_each_child_node( cpus, npcpu )
>> +            {
>> +                if ( dt_device_type_is_equal(npcpu, "cpu") )
>> +                {
>> +                    node_name = strrchr(dt_node_full_name(npcpu), '/');
>> +                    if ( node_name )
>> +                        node_name++;
>
> IIRC, it's not possible to have an empty node_name here. The node name
> will always be /cpus/name.
I'll do it in the next patch-set.

> I would turn this if to an ASSERT, and drop the if just below.
>
>> +
>> +                    if ( node_name && *node_name )
>> +                    {
>
> Regards,
>
> --
> Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 10/13] xen: arm: implement platform hypercall
  2014-10-07 15:39   ` Julien Grall
@ 2014-10-09  6:11     ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:11 UTC (permalink / raw)
  To: Julien Grall; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 6:39 PM, Julien Grall <julien.grall@linaro.org> wrote:
> Hi Oleksandr,
>
> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>> +ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>> +{
>> +    ret_t ret = 0;
>> +    struct xen_platform_op curop, *op = &curop;
>> +
>> +    if ( copy_from_guest(op, u_xenpf_op, 1) )
>> +        return -EFAULT;
>> +
>> +    if ( op->interface_version != XENPF_INTERFACE_VERSION )
>> +        return -EACCES;
>
> Why did you drop the XSM check here?
>
> Overall, the skeleton of this function is very similar to the x86. I
> would move the common part in xen/common and add arch implementation
> when it's necessary. You can give a look to do_domctl and arch_do_domctl.
I'll do it in the next patch-set.

> Regards,
>
> --
> Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-07 14:44   ` Jan Beulich
  2014-10-08 13:51     ` Stefano Stabellini
@ 2014-10-09  6:13     ` Oleksandr Dmytryshyn
  1 sibling, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09  6:13 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Tue, Oct 7, 2014 at 5:44 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> This driver uses Dom0 to change frequencies on CPUs
>
> In which case its name should be dom0-cpufreq. But I very much
> question a model where it is not the hypervisor controlling aspects
> of physical CPUs.
I'll change the driver name to dom0-cpufreq in the next patch-set.

> Jan
>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global
  2014-10-09  6:09     ` Oleksandr Dmytryshyn
@ 2014-10-09 11:15       ` Julien Grall
  2014-10-09 11:40         ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-10-09 11:15 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

Hi Oleksandr,

On 10/09/2014 07:09 AM, Oleksandr Dmytryshyn wrote:
> On Tue, Oct 7, 2014 at 6:09 PM, Julien Grall <julien.grall@linaro.org> wrote:
>> Hi Oleksandr,
>>
>> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>>> This patch makes possible to use the dt_find_property function
>>> outside the device tree module.
>>
>> I can't find any usage of this function within your series. Any reason
>> to export it?
> This function is used by patch in this series
> ([RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq
> cpu drive).

I don't see anything using this function in PATCH #9.

Futhermore, this function has been exported in Xen since the commit
16f9ccb "xen/dts: Add dt_property_read_bool" (pushed in May).

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global
  2014-10-09 11:15       ` Julien Grall
@ 2014-10-09 11:40         ` Oleksandr Dmytryshyn
  0 siblings, 0 replies; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-09 11:40 UTC (permalink / raw)
  To: Julien Grall; +Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

On Thu, Oct 9, 2014 at 2:15 PM, Julien Grall <julien.grall@linaro.org> wrote:
> Hi Oleksandr,
>
> On 10/09/2014 07:09 AM, Oleksandr Dmytryshyn wrote:
>> On Tue, Oct 7, 2014 at 6:09 PM, Julien Grall <julien.grall@linaro.org> wrote:
>>> Hi Oleksandr,
>>>
>>> On 10/07/2014 03:19 PM, Oleksandr Dmytryshyn wrote:
>>>> This patch makes possible to use the dt_find_property function
>>>> outside the device tree module.
>>>
>>> I can't find any usage of this function within your series. Any reason
>>> to export it?
>> This function is used by patch in this series
>> ([RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq
>> cpu drive).
>
> I don't see anything using this function in PATCH #9.
>
> Futhermore, this function has been exported in Xen since the commit
> 16f9ccb "xen/dts: Add dt_property_read_bool" (pushed in May).
I'll drop my patch and use 16f9ccb "xen/dts: Add dt_property_read_bool" instead.


> Regards,
>
> --
> Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-08 13:51     ` Stefano Stabellini
@ 2014-10-10  9:00       ` Jan Beulich
  2014-10-10  9:04         ` Stefano Stabellini
  2014-10-10  9:39       ` Jan Beulich
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-10  9:00 UTC (permalink / raw)
  To: Stefano.Stabellini, Stefano Stabellini
  Cc: Oleksandr Dmytryshyn, Tim Deegan, Ian Campbell, xen-devel

>>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
> On Tue, 7 Oct 2014, Jan Beulich wrote:
>> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> > This driver uses Dom0 to change frequencies on CPUs
>> 
>> In which case its name should be dom0-cpufreq. But I very much
>> question a model where it is not the hypervisor controlling aspects
>> of physical CPUs.
> 
> Me too, however we had a long discussion (see
> CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
> Oleksandr and others thought that it would require too much drivers code
> to change cpu frequency directly in Xen on ARM
> (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
> CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
> 
> They might be right.

Sadly I have know of no way to spot a mail by ID In my mail client.
Could you instead provide a link to the respective entry in the list
archive?

Thanks, Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:00       ` Jan Beulich
@ 2014-10-10  9:04         ` Stefano Stabellini
  0 siblings, 0 replies; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-10  9:04 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano.Stabellini

On Fri, 10 Oct 2014, Jan Beulich wrote:
> >>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
> > On Tue, 7 Oct 2014, Jan Beulich wrote:
> >> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> >> > This driver uses Dom0 to change frequencies on CPUs
> >> 
> >> In which case its name should be dom0-cpufreq. But I very much
> >> question a model where it is not the hypervisor controlling aspects
> >> of physical CPUs.
> > 
> > Me too, however we had a long discussion (see
> > CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
> > Oleksandr and others thought that it would require too much drivers code
> > to change cpu frequency directly in Xen on ARM
> > (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
> > CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
> > 
> > They might be right.
> 
> Sadly I have know of no way to spot a mail by ID In my mail client.
> Could you instead provide a link to the respective entry in the list
> archive?

Sure. marc.info is very good at that: you can just use
marc.info/?i=message_id.

http://marc.info/?l=xen-devel&m=140784604110756
http://marc.info/?l=xen-devel&m=140932504131568
http://marc.info/?l=xen-devel&m=141034445300744

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-08 13:51     ` Stefano Stabellini
  2014-10-10  9:00       ` Jan Beulich
@ 2014-10-10  9:39       ` Jan Beulich
  2014-10-10  9:39         ` Stefano Stabellini
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-10  9:39 UTC (permalink / raw)
  To: Stefano.Stabellini, Stefano Stabellini
  Cc: Oleksandr Dmytryshyn, Tim Deegan, Ian Campbell, xen-devel

>>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
> On Tue, 7 Oct 2014, Jan Beulich wrote:
>> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> > This driver uses Dom0 to change frequencies on CPUs
>> 
>> In which case its name should be dom0-cpufreq. But I very much
>> question a model where it is not the hypervisor controlling aspects
>> of physical CPUs.
> 
> Me too, however we had a long discussion (see
> CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
> Oleksandr and others thought that it would require too much drivers code
> to change cpu frequency directly in Xen on ARM
> (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
> CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
> 
> They might be right.

I continue to disagree, despite understanding some of the points
they make. ACPI has obtained I2C resource handling a while ago,
so rather than keeping I2C out of Xen we should rather consider
updating the few ACPI pieces we have to be capable of handling
that resource type. Of course that's only useful if systems also
describe their frequency change procedure properly in ACPI (but
if they don't do now, I think with ARM moving the ACPI way we
can at least expect that to come).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:39       ` Jan Beulich
@ 2014-10-10  9:39         ` Stefano Stabellini
  2014-10-10  9:46           ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-10  9:39 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano.Stabellini

On Fri, 10 Oct 2014, Jan Beulich wrote:
> >>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
> > On Tue, 7 Oct 2014, Jan Beulich wrote:
> >> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> >> > This driver uses Dom0 to change frequencies on CPUs
> >> 
> >> In which case its name should be dom0-cpufreq. But I very much
> >> question a model where it is not the hypervisor controlling aspects
> >> of physical CPUs.
> > 
> > Me too, however we had a long discussion (see
> > CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
> > Oleksandr and others thought that it would require too much drivers code
> > to change cpu frequency directly in Xen on ARM
> > (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
> > CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
> > 
> > They might be right.
> 
> I continue to disagree, despite understanding some of the points
> they make. ACPI has obtained I2C resource handling a while ago,
> so rather than keeping I2C out of Xen we should rather consider
> updating the few ACPI pieces we have to be capable of handling
> that resource type. Of course that's only useful if systems also
> describe their frequency change procedure properly in ACPI (but
> if they don't do now, I think with ARM moving the ACPI way we
> can at least expect that to come).

ACPI is not coming to ARM in general, only to (some?) ARM servers.
Device Tree is alive and well and we have to keep supporting it for all
the other systems.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:39         ` Stefano Stabellini
@ 2014-10-10  9:46           ` Jan Beulich
  2014-10-10  9:54             ` Stefano Stabellini
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-10  9:46 UTC (permalink / raw)
  To: Stefano.Stabellini, Stefano Stabellini
  Cc: Oleksandr Dmytryshyn, Tim Deegan, Ian Campbell, xen-devel

>>> On 10.10.14 at 11:39, <stefano.stabellini@eu.citrix.com> wrote:
> On Fri, 10 Oct 2014, Jan Beulich wrote:
>> >>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
>> > On Tue, 7 Oct 2014, Jan Beulich wrote:
>> >> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> >> > This driver uses Dom0 to change frequencies on CPUs
>> >> 
>> >> In which case its name should be dom0-cpufreq. But I very much
>> >> question a model where it is not the hypervisor controlling aspects
>> >> of physical CPUs.
>> > 
>> > Me too, however we had a long discussion (see
>> > CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
>> > Oleksandr and others thought that it would require too much drivers code
>> > to change cpu frequency directly in Xen on ARM
>> > (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
>> > CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
>> > 
>> > They might be right.
>> 
>> I continue to disagree, despite understanding some of the points
>> they make. ACPI has obtained I2C resource handling a while ago,
>> so rather than keeping I2C out of Xen we should rather consider
>> updating the few ACPI pieces we have to be capable of handling
>> that resource type. Of course that's only useful if systems also
>> describe their frequency change procedure properly in ACPI (but
>> if they don't do now, I think with ARM moving the ACPI way we
>> can at least expect that to come).
> 
> ACPI is not coming to ARM in general, only to (some?) ARM servers.
> Device Tree is alive and well and we have to keep supporting it for all
> the other systems.

Okay, but that doesn't change the picture: I2C support is going to
be useful (needed?) for ACPI sooner or later, so having something
(hopefully minimalistic) in the hypervisor doesn't sound like all that
bad an idea, and could then be used outside of ACPI too for ARM.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:46           ` Jan Beulich
@ 2014-10-10  9:54             ` Stefano Stabellini
  2014-10-10  9:59               ` Ian Campbell
  2014-10-10 10:40               ` Jan Beulich
  0 siblings, 2 replies; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-10  9:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano.Stabellini

On Fri, 10 Oct 2014, Jan Beulich wrote:
> >>> On 10.10.14 at 11:39, <stefano.stabellini@eu.citrix.com> wrote:
> > On Fri, 10 Oct 2014, Jan Beulich wrote:
> >> >>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
> >> > On Tue, 7 Oct 2014, Jan Beulich wrote:
> >> >> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
> >> >> > This driver uses Dom0 to change frequencies on CPUs
> >> >> 
> >> >> In which case its name should be dom0-cpufreq. But I very much
> >> >> question a model where it is not the hypervisor controlling aspects
> >> >> of physical CPUs.
> >> > 
> >> > Me too, however we had a long discussion (see
> >> > CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
> >> > Oleksandr and others thought that it would require too much drivers code
> >> > to change cpu frequency directly in Xen on ARM
> >> > (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
> >> > CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
> >> > 
> >> > They might be right.
> >> 
> >> I continue to disagree, despite understanding some of the points
> >> they make. ACPI has obtained I2C resource handling a while ago,
> >> so rather than keeping I2C out of Xen we should rather consider
> >> updating the few ACPI pieces we have to be capable of handling
> >> that resource type. Of course that's only useful if systems also
> >> describe their frequency change procedure properly in ACPI (but
> >> if they don't do now, I think with ARM moving the ACPI way we
> >> can at least expect that to come).
> > 
> > ACPI is not coming to ARM in general, only to (some?) ARM servers.
> > Device Tree is alive and well and we have to keep supporting it for all
> > the other systems.
> 
> Okay, but that doesn't change the picture: I2C support is going to
> be useful (needed?) for ACPI sooner or later, so having something
> (hopefully minimalistic) in the hypervisor doesn't sound like all that
> bad an idea, and could then be used outside of ACPI too for ARM.

Why is I2C needed for ACPI? I thought that all the freq changing ops
would be hidden behind AML methods.

Honestly not knowing how much code is required to have I2C support in
Xen, it is difficult for me to guess what would be the best approach.
The GlobalLogic guys seem to think too much.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:54             ` Stefano Stabellini
@ 2014-10-10  9:59               ` Ian Campbell
  2014-10-10 12:51                 ` Jan Beulich
  2014-10-10 10:40               ` Jan Beulich
  1 sibling, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-10-10  9:59 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Tim Deegan, Oleksandr Dmytryshyn, Stefano.Stabellini,
	Jan Beulich, xen-devel

On Fri, 2014-10-10 at 10:54 +0100, Stefano Stabellini wrote:
> On Fri, 10 Oct 2014, Jan Beulich wrote:
> > >> ACPI has obtained I2C resource handling a while ago,
> > >> 
> Why is I2C needed for ACPI? I thought that all the freq changing ops
> would be hidden behind AML methods.

>From what Jan says it sounds to me like AML can now invoke i2c
operations...

> Honestly not knowing how much code is required to have I2C support in
> Xen, it is difficult for me to guess what would be the best approach.
> The GlobalLogic guys seem to think too much.

A simple i2c driver (without all the generic framework/bus
infrastructure which Linux has) is pretty simple.

I think the biggest complexity would come from i2c busses with both
cpufreq and other devices on them and managing the potentially shared
accesses.

Presumably ACPI systems must avoid having buses which are accessed both
via AML and by the OS directly. I expect DT has no such restriction.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:54             ` Stefano Stabellini
  2014-10-10  9:59               ` Ian Campbell
@ 2014-10-10 10:40               ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-10 10:40 UTC (permalink / raw)
  To: Stefano.Stabellini, Stefano Stabellini
  Cc: Oleksandr Dmytryshyn, Tim Deegan, Ian Campbell, xen-devel

>>> On 10.10.14 at 11:54, <stefano.stabellini@eu.citrix.com> wrote:
> On Fri, 10 Oct 2014, Jan Beulich wrote:
>> >>> On 10.10.14 at 11:39, <stefano.stabellini@eu.citrix.com> wrote:
>> > On Fri, 10 Oct 2014, Jan Beulich wrote:
>> >> >>> On 08.10.14 at 15:51, <stefano.stabellini@eu.citrix.com> wrote:
>> >> > On Tue, 7 Oct 2014, Jan Beulich wrote:
>> >> >> >>> On 07.10.14 at 16:19, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> >> >> > This driver uses Dom0 to change frequencies on CPUs
>> >> >> 
>> >> >> In which case its name should be dom0-cpufreq. But I very much
>> >> >> question a model where it is not the hypervisor controlling aspects
>> >> >> of physical CPUs.
>> >> > 
>> >> > Me too, however we had a long discussion (see
>> >> > CAN58jiuVOJMX2-U=Odqrjtr1agNPSRnS1nXURYitc8AC8FgH3g@mail.gmail.com) and
>> >> > Oleksandr and others thought that it would require too much drivers code
>> >> > to change cpu frequency directly in Xen on ARM
>> >> > (CAH_mUMNQLHeOWFC_SNB_8BjBz9rOs=moYOUFFhtOXo_WPZTa7w@mail.gmail.com and
>> >> > CAH_mUMM0iSCcCcYz1B13p5YdS+wvgBOMVJh-871v0Ga0f1bH8Q@mail.gmail.com).
>> >> > 
>> >> > They might be right.
>> >> 
>> >> I continue to disagree, despite understanding some of the points
>> >> they make. ACPI has obtained I2C resource handling a while ago,
>> >> so rather than keeping I2C out of Xen we should rather consider
>> >> updating the few ACPI pieces we have to be capable of handling
>> >> that resource type. Of course that's only useful if systems also
>> >> describe their frequency change procedure properly in ACPI (but
>> >> if they don't do now, I think with ARM moving the ACPI way we
>> >> can at least expect that to come).
>> > 
>> > ACPI is not coming to ARM in general, only to (some?) ARM servers.
>> > Device Tree is alive and well and we have to keep supporting it for all
>> > the other systems.
>> 
>> Okay, but that doesn't change the picture: I2C support is going to
>> be useful (needed?) for ACPI sooner or later, so having something
>> (hopefully minimalistic) in the hypervisor doesn't sound like all that
>> bad an idea, and could then be used outside of ACPI too for ARM.
> 
> Why is I2C needed for ACPI? I thought that all the freq changing ops
> would be hidden behind AML methods.

But the AML methods specify certain resources to be read/written.
Apart from MMIO and I/O ports (the latter on x86 only), this could
now also be an I2C access aiui.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10  9:59               ` Ian Campbell
@ 2014-10-10 12:51                 ` Jan Beulich
  2014-10-10 14:42                   ` Stefano Stabellini
  2014-10-10 15:19                   ` Ian Campbell
  0 siblings, 2 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-10 12:51 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini
  Cc: Tim Deegan, Oleksandr Dmytryshyn, Stefano.Stabellini, xen-devel

>>> On 10.10.14 at 11:59, <Ian.Campbell@citrix.com> wrote:
> A simple i2c driver (without all the generic framework/bus
> infrastructure which Linux has) is pretty simple.
> 
> I think the biggest complexity would come from i2c busses with both
> cpufreq and other devices on them and managing the potentially shared
> accesses.

And the recently added XENPF_resource_op would seem a pretty
good candidate for this (except that it requires the Dom0 kernel
code to stop accessing hardware directly, and instead go through
this hypercall).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10 12:51                 ` Jan Beulich
@ 2014-10-10 14:42                   ` Stefano Stabellini
  2014-10-13  8:56                     ` Oleksandr Dmytryshyn
  2014-10-10 15:19                   ` Ian Campbell
  1 sibling, 1 reply; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-10 14:42 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano.Stabellini

On Fri, 10 Oct 2014, Jan Beulich wrote:
> >>> On 10.10.14 at 11:59, <Ian.Campbell@citrix.com> wrote:
> > A simple i2c driver (without all the generic framework/bus
> > infrastructure which Linux has) is pretty simple.
> > 
> > I think the biggest complexity would come from i2c busses with both
> > cpufreq and other devices on them and managing the potentially shared
> > accesses.
> 
> And the recently added XENPF_resource_op would seem a pretty
> good candidate for this (except that it requires the Dom0 kernel
> code to stop accessing hardware directly, and instead go through
> this hypercall).


Oleksandr, how would you feel about this change of direction?

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10 12:51                 ` Jan Beulich
  2014-10-10 14:42                   ` Stefano Stabellini
@ 2014-10-10 15:19                   ` Ian Campbell
  1 sibling, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-10-10 15:19 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Tim Deegan, Oleksandr Dmytryshyn, xen-devel, Stefano.Stabellini,
	Stefano Stabellini

On Fri, 2014-10-10 at 13:51 +0100, Jan Beulich wrote:
> >>> On 10.10.14 at 11:59, <Ian.Campbell@citrix.com> wrote:
> > A simple i2c driver (without all the generic framework/bus
> > infrastructure which Linux has) is pretty simple.
> > 
> > I think the biggest complexity would come from i2c busses with both
> > cpufreq and other devices on them and managing the potentially shared
> > accesses.
> 
> And the recently added XENPF_resource_op would seem a pretty
> good candidate for this (except that it requires the Dom0 kernel
> code to stop accessing hardware directly, and instead go through
> this hypercall).

We'd need to introduce a dtb binding for a "pv i2c host controller"
which we would use to replace the actual one for dom0. That might be
doable I think, so long as we take care to preserve the relationships
with other nodes which might reference it.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-10 14:42                   ` Stefano Stabellini
@ 2014-10-13  8:56                     ` Oleksandr Dmytryshyn
  2014-10-13  9:39                       ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-13  8:56 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, Jan Beulich, xen-devel

On Fri, Oct 10, 2014 at 5:42 PM, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
>
> On Fri, 10 Oct 2014, Jan Beulich wrote:
> > >>> On 10.10.14 at 11:59, <Ian.Campbell@citrix.com> wrote:
> > > A simple i2c driver (without all the generic framework/bus
> > > infrastructure which Linux has) is pretty simple.
> > >
> > > I think the biggest complexity would come from i2c busses with both
> > > cpufreq and other devices on them and managing the potentially shared
> > > accesses.
> >
> > And the recently added XENPF_resource_op would seem a pretty
> > good candidate for this (except that it requires the Dom0 kernel
> > code to stop accessing hardware directly, and instead go through
> > this hypercall).
>
>
> Oleksandr, how would you feel about this change of direction?
I see that XENPF_resource_op is used to safely read/write MSR.
In my case the cpufreq governor driver is inside XEN and the rest of the cpufreq
driver is inside Dom0. Dom0 directly changes CPUs frequency. I don't know how
to use XENPF_resource_op for ARM. If we want to change CPUs frequency that we
should change the voltage and write something to the clock control registers in
ARM. If the I2C driver will be virtualized then Regulator framework
can be inside
Dom0. But every ARM processor has own clock control registers with different
addresses. How in this case I should handle this situation? May be
Clock framework
should be virtualized too? But this is huge framework. Could XENPF_resource_op
be used to read/write given value at given address (not predefined addresses
such as MSR for X86)? If yes that this is possible to not access the hardware
directly from dom0. But Clock framework in Dom0 can read/write a lot of
registers and there will be too much hypercalls.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13  8:56                     ` Oleksandr Dmytryshyn
@ 2014-10-13  9:39                       ` Jan Beulich
  2014-10-13 11:59                         ` Oleksandr Dmytryshyn
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-13  9:39 UTC (permalink / raw)
  To: Stefano Stabellini, Oleksandr Dmytryshyn
  Cc: Tim Deegan, Stefano Stabellini, Ian Campbell, xen-devel

>>> On 13.10.14 at 10:56, <oleksandr.dmytryshyn@globallogic.com> wrote:
> On Fri, Oct 10, 2014 at 5:42 PM, Stefano Stabellini
>> Oleksandr, how would you feel about this change of direction?
> I see that XENPF_resource_op is used to safely read/write MSR.
> In my case the cpufreq governor driver is inside XEN and the rest of the 
> cpufreq
> driver is inside Dom0. Dom0 directly changes CPUs frequency. I don't know 
> how
> to use XENPF_resource_op for ARM. If we want to change CPUs frequency that 
> we
> should change the voltage and write something to the clock control registers 
> in
> ARM.

You didn't understand then: Use of XENPF_resource_op was only
suggested to help with handling both Dom0-based and Xen-initiated
accesses to the same I2C bus, which would be necessary as a result
of keeping control over CPU frequency in the hypervisor.

> If the I2C driver will be virtualized then Regulator framework
> can be inside
> Dom0. But every ARM processor has own clock control registers with different
> addresses. How in this case I should handle this situation? May be
> Clock framework
> should be virtualized too? But this is huge framework. Could 
> XENPF_resource_op
> be used to read/write given value at given address (not predefined addresses
> such as MSR for X86)? If yes that this is possible to not access the 
> hardware
> directly from dom0. But Clock framework in Dom0 can read/write a lot of
> registers and there will be too much hypercalls.

I think the question is mostly moot with the above, but just in case
there's still some use case: Any resource could theoretically be
accessed this way. The only requirement for each individual
resource kind is that it be enumerable. And I'm sure these special
registers can be enumerated (e.g. using the system register
numbering, if it's that how they get represented).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13  9:39                       ` Jan Beulich
@ 2014-10-13 11:59                         ` Oleksandr Dmytryshyn
  2014-10-13 12:28                           ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Oleksandr Dmytryshyn @ 2014-10-13 11:59 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Tim Deegan, xen-devel, Stefano Stabellini, Ian Campbell,
	Stefano Stabellini

On Mon, Oct 13, 2014 at 12:39 PM, Jan Beulich <JBeulich@suse.com> wrote:
>
> >>> On 13.10.14 at 10:56, <oleksandr.dmytryshyn@globallogic.com> wrote:
> > On Fri, Oct 10, 2014 at 5:42 PM, Stefano Stabellini
> >> Oleksandr, how would you feel about this change of direction?
> > I see that XENPF_resource_op is used to safely read/write MSR.
> > In my case the cpufreq governor driver is inside XEN and the rest of the
> > cpufreq
> > driver is inside Dom0. Dom0 directly changes CPUs frequency. I don't know
> > how
> > to use XENPF_resource_op for ARM. If we want to change CPUs frequency that
> > we
> > should change the voltage and write something to the clock control registers
> > in
> > ARM.
>
> You didn't understand then: Use of XENPF_resource_op was only
> suggested to help with handling both Dom0-based and Xen-initiated
> accesses to the same I2C bus, which would be necessary as a result
> of keeping control over CPU frequency in the hypervisor.
>
> > If the I2C driver will be virtualized then Regulator framework
> > can be inside
> > Dom0. But every ARM processor has own clock control registers with different
> > addresses. How in this case I should handle this situation? May be
> > Clock framework
> > should be virtualized too? But this is huge framework. Could
> > XENPF_resource_op
> > be used to read/write given value at given address (not predefined addresses
> > such as MSR for X86)? If yes that this is possible to not access the
> > hardware
> > directly from dom0. But Clock framework in Dom0 can read/write a lot of
> > registers and there will be too much hypercalls.
>
> I think the question is mostly moot with the above, but just in case
> there's still some use case: Any resource could theoretically be
> accessed this way. The only requirement for each individual
> resource kind is that it be enumerable. And I'm sure these special
> registers can be enumerated (e.g. using the system register
> numbering, if it's that how they get represented).
>
> Jan
>

There are few reasons to not implement PV I2C in Xen:
1. It is difficult to implement concurrent access to I2C controller
2. I2C code is closely integrated to the Linux kernel code and
I2C driver has lots of levels of abstraction. It is very difficult to cut
I2C code from kernel and make kernel working without it. Kernel folks
will not take this solution to the mainline.
3. Implementation of the  I2C driver in Xen will rather be more complex
than simple.
4. There will be overhead to do all steps above.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13 11:59                         ` Oleksandr Dmytryshyn
@ 2014-10-13 12:28                           ` Jan Beulich
  2014-10-13 13:38                             ` Andrii Tseglytskyi
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-13 12:28 UTC (permalink / raw)
  To: Oleksandr Dmytryshyn
  Cc: Tim Deegan, xen-devel, Stefano Stabellini, Ian Campbell,
	Stefano Stabellini

>>> On 13.10.14 at 13:59, <oleksandr.dmytryshyn@globallogic.com> wrote:
> There are few reasons to not implement PV I2C in Xen:
> 1. It is difficult to implement concurrent access to I2C controller

I already outlined how I think this could be made work.

> 2. I2C code is closely integrated to the Linux kernel code and
> I2C driver has lots of levels of abstraction. It is very difficult to cut
> I2C code from kernel and make kernel working without it. Kernel folks
> will not take this solution to the mainline.
> 3. Implementation of the  I2C driver in Xen will rather be more complex
> than simple.

Others seem to be of different opinion.

> 4. There will be overhead to do all steps above.

Not sure what you mean here.

In any event I don't think we should discard an architecturally clean
option before having tried it. The Dom0-based CPUfreq handling in
x86 also had turned out a mostly dead end (and I'd be glad to see
it gone altogether from the sources).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13 12:28                           ` Jan Beulich
@ 2014-10-13 13:38                             ` Andrii Tseglytskyi
  2014-10-13 14:11                               ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-13 13:38 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini

Hi Jan,

On Mon, Oct 13, 2014 at 3:28 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 13.10.14 at 13:59, <oleksandr.dmytryshyn@globallogic.com> wrote:
>> There are few reasons to not implement PV I2C in Xen:
>> 1. It is difficult to implement concurrent access to I2C controller
>
> I already outlined how I think this could be made work.
>

It should be noticed that sometimes I2C transactions require platform
specific IPs.
For example OMAP3+ platforms contain HW spinlock IP (which is a real
HW module with its own clocks).
Each i2c_send call must acquire this HW spinlock. And this is
something we can't implement in Xen hypervisor.

>> 2. I2C code is closely integrated to the Linux kernel code and
>> I2C driver has lots of levels of abstraction. It is very difficult to cut
>> I2C code from kernel and make kernel working without it. Kernel folks
>> will not take this solution to the mainline.
>> 3. Implementation of the  I2C driver in Xen will rather be more complex
>> than simple.
>
> Others seem to be of different opinion.
>
>> 4. There will be overhead to do all steps above.
>
> Not sure what you mean here.
>

I see the following concern here:

It should be noticed that almost all peripheral uses I2C bus.
For example on our platform touchscreen uses I2C (jacinto6 evm board).
Each scroll produces about 50 I2C commands.
It means 50 hypercalls in the line to hypervisor, and 100 context
switches between hypervisor and dom0.

Taking in account all the above - we should think twice about even
simple I2C driver which may control voltage regulator.

Regards,
Andrii


-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13 13:38                             ` Andrii Tseglytskyi
@ 2014-10-13 14:11                               ` Jan Beulich
  2014-10-13 14:29                                 ` Andrii Tseglytskyi
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-10-13 14:11 UTC (permalink / raw)
  To: Andrii Tseglytskyi
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini

>>> On 13.10.14 at 15:38, <andrii.tseglytskyi@globallogic.com> wrote:
> On Mon, Oct 13, 2014 at 3:28 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 13.10.14 at 13:59, <oleksandr.dmytryshyn@globallogic.com> wrote:
>>> There are few reasons to not implement PV I2C in Xen:
>>> 1. It is difficult to implement concurrent access to I2C controller
>>
>> I already outlined how I think this could be made work.
>>
> 
> It should be noticed that sometimes I2C transactions require platform
> specific IPs.
> For example OMAP3+ platforms contain HW spinlock IP (which is a real
> HW module with its own clocks).
> Each i2c_send call must acquire this HW spinlock. And this is
> something we can't implement in Xen hypervisor.

Do you really mean "can't", or rather "don't want to"? It's very
hard for me to imagine something that absolutely can't be done
in the hypervisor.

>>> 2. I2C code is closely integrated to the Linux kernel code and
>>> I2C driver has lots of levels of abstraction. It is very difficult to cut
>>> I2C code from kernel and make kernel working without it. Kernel folks
>>> will not take this solution to the mainline.
>>> 3. Implementation of the  I2C driver in Xen will rather be more complex
>>> than simple.
>>
>> Others seem to be of different opinion.
>>
>>> 4. There will be overhead to do all steps above.
>>
>> Not sure what you mean here.
>>
> 
> I see the following concern here:
> 
> It should be noticed that almost all peripheral uses I2C bus.
> For example on our platform touchscreen uses I2C (jacinto6 evm board).
> Each scroll produces about 50 I2C commands.
> It means 50 hypercalls in the line to hypervisor, and 100 context
> switches between hypervisor and dom0.
> 
> Taking in account all the above - we should think twice about even
> simple I2C driver which may control voltage regulator.

Leaving aside that there are no real context switches between a
domain and the hypervisor (only domains, or more precisely vCPU-s,
get context switched), I'm not sure we need to be worried by these
numbers. Whether they're problematic depends significantly on the
time a full I2C command takes to issue (and perhaps complete). And
then I'm sure you're aware that hypercalls can be batched, so as
long as not every of these 50 commands depends on results from
the immediately preceding one, the hypercall cost can certainly be
amortized to a certain degree.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13 14:11                               ` Jan Beulich
@ 2014-10-13 14:29                                 ` Andrii Tseglytskyi
  2014-10-14 12:20                                   ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-13 14:29 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini

On Mon, Oct 13, 2014 at 5:11 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 13.10.14 at 15:38, <andrii.tseglytskyi@globallogic.com> wrote:
>> On Mon, Oct 13, 2014 at 3:28 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>> On 13.10.14 at 13:59, <oleksandr.dmytryshyn@globallogic.com> wrote:
>>>> There are few reasons to not implement PV I2C in Xen:
>>>> 1. It is difficult to implement concurrent access to I2C controller
>>>
>>> I already outlined how I think this could be made work.
>>>
>>
>> It should be noticed that sometimes I2C transactions require platform
>> specific IPs.
>> For example OMAP3+ platforms contain HW spinlock IP (which is a real
>> HW module with its own clocks).
>> Each i2c_send call must acquire this HW spinlock. And this is
>> something we can't implement in Xen hypervisor.
>
> Do you really mean "can't", or rather "don't want to"? It's very
> hard for me to imagine something that absolutely can't be done
> in the hypervisor.
>

I mean that we must deal with platform specific IP in this case. This
is dependency from specific HW, and driver will not be simple and
generic.
Also I think such interactions are out of scope for hypervisor.
What do you think?

>>>> 2. I2C code is closely integrated to the Linux kernel code and
>>>> I2C driver has lots of levels of abstraction. It is very difficult to cut
>>>> I2C code from kernel and make kernel working without it. Kernel folks
>>>> will not take this solution to the mainline.
>>>> 3. Implementation of the  I2C driver in Xen will rather be more complex
>>>> than simple.
>>>
>>> Others seem to be of different opinion.
>>>
>>>> 4. There will be overhead to do all steps above.
>>>
>>> Not sure what you mean here.
>>>
>>
>> I see the following concern here:
>>
>> It should be noticed that almost all peripheral uses I2C bus.
>> For example on our platform touchscreen uses I2C (jacinto6 evm board).
>> Each scroll produces about 50 I2C commands.
>> It means 50 hypercalls in the line to hypervisor, and 100 context
>> switches between hypervisor and dom0.
>>
>> Taking in account all the above - we should think twice about even
>> simple I2C driver which may control voltage regulator.
>
> Leaving aside that there are no real context switches between a
> domain and the hypervisor (only domains, or more precisely vCPU-s,
> get context switched), I'm not sure we need to be worried by these
> numbers. Whether they're problematic depends significantly on the
> time a full I2C command takes to issue (and perhaps complete). And
> then I'm sure you're aware that hypercalls can be batched, so as
> long as not every of these 50 commands depends on results from
> the immediately preceding one, the hypercall cost can certainly be
> amortized to a certain degree.

But in case if each I2C command depends on results of previous one -
we can't use such calls, right? Can we really rely on this?
Some time ago I had a model (for testing which is not related to this
thread) where I sent about 20 hypercalls each second.
I observed lugs in such use cases as Video playback in domU (Android
Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
will be fine and we can send as many hypercalls as we want. But I'm
worrying in our case this will not work.

Regards,
Andrii

>
> Jan
>



-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-13 14:29                                 ` Andrii Tseglytskyi
@ 2014-10-14 12:20                                   ` Jan Beulich
  2014-10-14 12:39                                     ` Andrii Tseglytskyi
  2014-10-14 12:51                                     ` Stefano Stabellini
  0 siblings, 2 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-14 12:20 UTC (permalink / raw)
  To: Andrii Tseglytskyi
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini

>>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
> On Mon, Oct 13, 2014 at 5:11 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 13.10.14 at 15:38, <andrii.tseglytskyi@globallogic.com> wrote:
>>> It should be noticed that sometimes I2C transactions require platform
>>> specific IPs.
>>> For example OMAP3+ platforms contain HW spinlock IP (which is a real
>>> HW module with its own clocks).
>>> Each i2c_send call must acquire this HW spinlock. And this is
>>> something we can't implement in Xen hypervisor.
>>
>> Do you really mean "can't", or rather "don't want to"? It's very
>> hard for me to imagine something that absolutely can't be done
>> in the hypervisor.
>>
> 
> I mean that we must deal with platform specific IP in this case. This
> is dependency from specific HW, and driver will not be simple and
> generic.
> Also I think such interactions are out of scope for hypervisor.
> What do you think?

Nothing is really out of scope for the hypervisor. It's always a
matter of judgment, and looking at the Linux i2c driver subtree I
don't view its size as problematic (the more that I don't think
you'd need all of it).

>> Leaving aside that there are no real context switches between a
>> domain and the hypervisor (only domains, or more precisely vCPU-s,
>> get context switched), I'm not sure we need to be worried by these
>> numbers. Whether they're problematic depends significantly on the
>> time a full I2C command takes to issue (and perhaps complete). And
>> then I'm sure you're aware that hypercalls can be batched, so as
>> long as not every of these 50 commands depends on results from
>> the immediately preceding one, the hypercall cost can certainly be
>> amortized to a certain degree.
> 
> But in case if each I2C command depends on results of previous one -
> we can't use such calls, right? Can we really rely on this?
> Some time ago I had a model (for testing which is not related to this
> thread) where I sent about 20 hypercalls each second.
> I observed lugs in such use cases as Video playback in domU (Android
> Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
> will be fine and we can send as many hypercalls as we want. But I'm
> worrying in our case this will not work.

If 20 hypercalls a second are a problem, then I think the device isn't
capable enough in the first place to run a virtualized workload, and
if it's so overloaded it's likely also not really useful to reduce the
CPU frequency (as then you'd end up having even more performance
problems).

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 12:20                                   ` Jan Beulich
@ 2014-10-14 12:39                                     ` Andrii Tseglytskyi
  2014-10-14 12:51                                     ` Stefano Stabellini
  1 sibling, 0 replies; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-14 12:39 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini

Hi Jan,

On Tue, Oct 14, 2014 at 3:20 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
>> On Mon, Oct 13, 2014 at 5:11 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>> On 13.10.14 at 15:38, <andrii.tseglytskyi@globallogic.com> wrote:
>>>> It should be noticed that sometimes I2C transactions require platform
>>>> specific IPs.
>>>> For example OMAP3+ platforms contain HW spinlock IP (which is a real
>>>> HW module with its own clocks).
>>>> Each i2c_send call must acquire this HW spinlock. And this is
>>>> something we can't implement in Xen hypervisor.
>>>
>>> Do you really mean "can't", or rather "don't want to"? It's very
>>> hard for me to imagine something that absolutely can't be done
>>> in the hypervisor.
>>>
>>
>> I mean that we must deal with platform specific IP in this case. This
>> is dependency from specific HW, and driver will not be simple and
>> generic.
>> Also I think such interactions are out of scope for hypervisor.
>> What do you think?
>
> Nothing is really out of scope for the hypervisor. It's always a
> matter of judgment, and looking at the Linux i2c driver subtree I
> don't view its size as problematic (the more that I don't think
> you'd need all of it).
>

I would need to sync with dom0 I2C subtree. Taking in account that a
lot of peripheral uses I2C commands as low level command interface I
would need to know about this peripheral inside Xen, otherwise how can
I sync with it? Why should Xen maintain platform specific peripherals,
if dom0 already does this? I think it is overhead.


>>> Leaving aside that there are no real context switches between a
>>> domain and the hypervisor (only domains, or more precisely vCPU-s,
>>> get context switched), I'm not sure we need to be worried by these
>>> numbers. Whether they're problematic depends significantly on the
>>> time a full I2C command takes to issue (and perhaps complete). And
>>> then I'm sure you're aware that hypercalls can be batched, so as
>>> long as not every of these 50 commands depends on results from
>>> the immediately preceding one, the hypercall cost can certainly be
>>> amortized to a certain degree.
>>
>> But in case if each I2C command depends on results of previous one -
>> we can't use such calls, right? Can we really rely on this?
>> Some time ago I had a model (for testing which is not related to this
>> thread) where I sent about 20 hypercalls each second.
>> I observed lugs in such use cases as Video playback in domU (Android
>> Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
>> will be fine and we can send as many hypercalls as we want. But I'm
>> worrying in our case this will not work.
>
> If 20 hypercalls a second are a problem, then I think the device isn't
> capable enough in the first place to run a virtualized workload, and
> if it's so overloaded it's likely also not really useful to reduce the
> CPU frequency (as then you'd end up having even more performance
> problems).

For sure OMAP5+ platforms are capable enough to run virtualized workload.
But this solution may reduce performance a lot. These 20 hypercalls
per second will be quite heavy in our case.

regards,
Andrii

>
> Jan
>



-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 12:20                                   ` Jan Beulich
  2014-10-14 12:39                                     ` Andrii Tseglytskyi
@ 2014-10-14 12:51                                     ` Stefano Stabellini
  2014-10-14 12:58                                       ` Andrii Tseglytskyi
  1 sibling, 1 reply; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-14 12:51 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini, Andrii Tseglytskyi

On Tue, 14 Oct 2014, Jan Beulich wrote:
> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
> >> Leaving aside that there are no real context switches between a
> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
> >> get context switched), I'm not sure we need to be worried by these
> >> numbers. Whether they're problematic depends significantly on the
> >> time a full I2C command takes to issue (and perhaps complete). And
> >> then I'm sure you're aware that hypercalls can be batched, so as
> >> long as not every of these 50 commands depends on results from
> >> the immediately preceding one, the hypercall cost can certainly be
> >> amortized to a certain degree.
> > 
> > But in case if each I2C command depends on results of previous one -
> > we can't use such calls, right? Can we really rely on this?
> > Some time ago I had a model (for testing which is not related to this
> > thread) where I sent about 20 hypercalls each second.
> > I observed lugs in such use cases as Video playback in domU (Android
> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
> > will be fine and we can send as many hypercalls as we want. But I'm
> > worrying in our case this will not work.
> 
> If 20 hypercalls a second are a problem, then I think the device isn't
> capable enough in the first place to run a virtualized workload, and
> if it's so overloaded it's likely also not really useful to reduce the
> CPU frequency (as then you'd end up having even more performance
> problems).
 
If we need 20 hypercalls a second by design, I think that we might have
a broken design. One thing is requiring hypercalls for configuration,
such us PCI config space accesses, but requiring hypercalls to issue
commands to a device is very different.
I didn't realize that high performance devices could usually be
connected via I2C.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 12:51                                     ` Stefano Stabellini
@ 2014-10-14 12:58                                       ` Andrii Tseglytskyi
  2014-10-14 13:00                                         ` Andrii Tseglytskyi
  0 siblings, 1 reply; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-14 12:58 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Tue, 14 Oct 2014, Jan Beulich wrote:
>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
>> >> Leaving aside that there are no real context switches between a
>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
>> >> get context switched), I'm not sure we need to be worried by these
>> >> numbers. Whether they're problematic depends significantly on the
>> >> time a full I2C command takes to issue (and perhaps complete). And
>> >> then I'm sure you're aware that hypercalls can be batched, so as
>> >> long as not every of these 50 commands depends on results from
>> >> the immediately preceding one, the hypercall cost can certainly be
>> >> amortized to a certain degree.
>> >
>> > But in case if each I2C command depends on results of previous one -
>> > we can't use such calls, right? Can we really rely on this?
>> > Some time ago I had a model (for testing which is not related to this
>> > thread) where I sent about 20 hypercalls each second.
>> > I observed lugs in such use cases as Video playback in domU (Android
>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
>> > will be fine and we can send as many hypercalls as we want. But I'm
>> > worrying in our case this will not work.
>>
>> If 20 hypercalls a second are a problem, then I think the device isn't
>> capable enough in the first place to run a virtualized workload, and
>> if it's so overloaded it's likely also not really useful to reduce the
>> CPU frequency (as then you'd end up having even more performance
>> problems).
>
> If we need 20 hypercalls a second by design, I think that we might have
> a broken design.

Agree.

> One thing is requiring hypercalls for configuration,
> such us PCI config space accesses, but requiring hypercalls to issue
> commands to a device is very different.
> I didn't realize that high performance devices could usually be
> connected via I2C.

This is a real example of touchscreen driver. Each scroll produces
about 50 I2C commands. If we decide to scroll all the time (why should
we limit this possibility?) - we will observe significant lags by this
design.

Regards,
Andrii

-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 12:58                                       ` Andrii Tseglytskyi
@ 2014-10-14 13:00                                         ` Andrii Tseglytskyi
  2014-10-14 13:05                                           ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-14 13:00 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

On Tue, Oct 14, 2014 at 3:58 PM, Andrii Tseglytskyi
<andrii.tseglytskyi@globallogic.com> wrote:
> On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
> <stefano.stabellini@eu.citrix.com> wrote:
>> On Tue, 14 Oct 2014, Jan Beulich wrote:
>>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
>>> >> Leaving aside that there are no real context switches between a
>>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
>>> >> get context switched), I'm not sure we need to be worried by these
>>> >> numbers. Whether they're problematic depends significantly on the
>>> >> time a full I2C command takes to issue (and perhaps complete). And
>>> >> then I'm sure you're aware that hypercalls can be batched, so as
>>> >> long as not every of these 50 commands depends on results from
>>> >> the immediately preceding one, the hypercall cost can certainly be
>>> >> amortized to a certain degree.
>>> >
>>> > But in case if each I2C command depends on results of previous one -
>>> > we can't use such calls, right? Can we really rely on this?
>>> > Some time ago I had a model (for testing which is not related to this
>>> > thread) where I sent about 20 hypercalls each second.
>>> > I observed lugs in such use cases as Video playback in domU (Android
>>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
>>> > will be fine and we can send as many hypercalls as we want. But I'm
>>> > worrying in our case this will not work.
>>>
>>> If 20 hypercalls a second are a problem, then I think the device isn't
>>> capable enough in the first place to run a virtualized workload, and
>>> if it's so overloaded it's likely also not really useful to reduce the
>>> CPU frequency (as then you'd end up having even more performance
>>> problems).
>>
>> If we need 20 hypercalls a second by design, I think that we might have
>> a broken design.
>
> Agree.
>
>> One thing is requiring hypercalls for configuration,
>> such us PCI config space accesses, but requiring hypercalls to issue
>> commands to a device is very different.
>> I didn't realize that high performance devices could usually be
>> connected via I2C.
>
> This is a real example of touchscreen driver. Each scroll produces
> about 50 I2C commands. If we decide to scroll all the time (why should
> we limit this possibility?) - we will observe significant lags by this
> design.
>

Especially with Audio playback in background (which also uses I2C),
and simultaneous request of frequency / voltage change.

> Regards,
> Andrii
>
> --
>
> Andrii Tseglytskyi | Embedded Dev
> GlobalLogic
> www.globallogic.com



-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 13:00                                         ` Andrii Tseglytskyi
@ 2014-10-14 13:05                                           ` Ian Campbell
  2014-10-14 13:07                                             ` Andrii Tseglytskyi
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-10-14 13:05 UTC (permalink / raw)
  To: Andrii Tseglytskyi
  Cc: Stefano Stabellini, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

On Tue, 2014-10-14 at 16:00 +0300, Andrii Tseglytskyi wrote:
> On Tue, Oct 14, 2014 at 3:58 PM, Andrii Tseglytskyi
> <andrii.tseglytskyi@globallogic.com> wrote:
> > On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
> > <stefano.stabellini@eu.citrix.com> wrote:
> >> On Tue, 14 Oct 2014, Jan Beulich wrote:
> >>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
> >>> >> Leaving aside that there are no real context switches between a
> >>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
> >>> >> get context switched), I'm not sure we need to be worried by these
> >>> >> numbers. Whether they're problematic depends significantly on the
> >>> >> time a full I2C command takes to issue (and perhaps complete). And
> >>> >> then I'm sure you're aware that hypercalls can be batched, so as
> >>> >> long as not every of these 50 commands depends on results from
> >>> >> the immediately preceding one, the hypercall cost can certainly be
> >>> >> amortized to a certain degree.
> >>> >
> >>> > But in case if each I2C command depends on results of previous one -
> >>> > we can't use such calls, right? Can we really rely on this?
> >>> > Some time ago I had a model (for testing which is not related to this
> >>> > thread) where I sent about 20 hypercalls each second.
> >>> > I observed lugs in such use cases as Video playback in domU (Android
> >>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
> >>> > will be fine and we can send as many hypercalls as we want. But I'm
> >>> > worrying in our case this will not work.
> >>>
> >>> If 20 hypercalls a second are a problem, then I think the device isn't
> >>> capable enough in the first place to run a virtualized workload, and
> >>> if it's so overloaded it's likely also not really useful to reduce the
> >>> CPU frequency (as then you'd end up having even more performance
> >>> problems).
> >>
> >> If we need 20 hypercalls a second by design, I think that we might have
> >> a broken design.
> >
> > Agree.
> >
> >> One thing is requiring hypercalls for configuration,
> >> such us PCI config space accesses, but requiring hypercalls to issue
> >> commands to a device is very different.
> >> I didn't realize that high performance devices could usually be
> >> connected via I2C.
> >
> > This is a real example of touchscreen driver. Each scroll produces
> > about 50 I2C commands. If we decide to scroll all the time (why should
> > we limit this possibility?) - we will observe significant lags by this
> > design.
> >
> 
> Especially with Audio playback in background (which also uses I2C),
> and simultaneous request of frequency / voltage change.
> 

Are audio, touchscreen and voltage control all on the same i2c bus /
behind the same i2c controller?

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 13:05                                           ` Ian Campbell
@ 2014-10-14 13:07                                             ` Andrii Tseglytskyi
  2014-10-15 10:55                                               ` Stefano Stabellini
  0 siblings, 1 reply; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-14 13:07 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Stefano Stabellini, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

On Tue, Oct 14, 2014 at 4:05 PM, Ian Campbell <ian.campbell@citrix.com> wrote:
> On Tue, 2014-10-14 at 16:00 +0300, Andrii Tseglytskyi wrote:
>> On Tue, Oct 14, 2014 at 3:58 PM, Andrii Tseglytskyi
>> <andrii.tseglytskyi@globallogic.com> wrote:
>> > On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
>> > <stefano.stabellini@eu.citrix.com> wrote:
>> >> On Tue, 14 Oct 2014, Jan Beulich wrote:
>> >>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
>> >>> >> Leaving aside that there are no real context switches between a
>> >>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
>> >>> >> get context switched), I'm not sure we need to be worried by these
>> >>> >> numbers. Whether they're problematic depends significantly on the
>> >>> >> time a full I2C command takes to issue (and perhaps complete). And
>> >>> >> then I'm sure you're aware that hypercalls can be batched, so as
>> >>> >> long as not every of these 50 commands depends on results from
>> >>> >> the immediately preceding one, the hypercall cost can certainly be
>> >>> >> amortized to a certain degree.
>> >>> >
>> >>> > But in case if each I2C command depends on results of previous one -
>> >>> > we can't use such calls, right? Can we really rely on this?
>> >>> > Some time ago I had a model (for testing which is not related to this
>> >>> > thread) where I sent about 20 hypercalls each second.
>> >>> > I observed lugs in such use cases as Video playback in domU (Android
>> >>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
>> >>> > will be fine and we can send as many hypercalls as we want. But I'm
>> >>> > worrying in our case this will not work.
>> >>>
>> >>> If 20 hypercalls a second are a problem, then I think the device isn't
>> >>> capable enough in the first place to run a virtualized workload, and
>> >>> if it's so overloaded it's likely also not really useful to reduce the
>> >>> CPU frequency (as then you'd end up having even more performance
>> >>> problems).
>> >>
>> >> If we need 20 hypercalls a second by design, I think that we might have
>> >> a broken design.
>> >
>> > Agree.
>> >
>> >> One thing is requiring hypercalls for configuration,
>> >> such us PCI config space accesses, but requiring hypercalls to issue
>> >> commands to a device is very different.
>> >> I didn't realize that high performance devices could usually be
>> >> connected via I2C.
>> >
>> > This is a real example of touchscreen driver. Each scroll produces
>> > about 50 I2C commands. If we decide to scroll all the time (why should
>> > we limit this possibility?) - we will observe significant lags by this
>> > design.
>> >
>>
>> Especially with Audio playback in background (which also uses I2C),
>> and simultaneous request of frequency / voltage change.
>>
>
> Are audio, touchscreen and voltage control all on the same i2c bus /
> behind the same i2c controller?
>

Yes. The same bus and the same controller.

> Ian.
>
>



-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-14 13:07                                             ` Andrii Tseglytskyi
@ 2014-10-15 10:55                                               ` Stefano Stabellini
  2014-10-15 11:17                                                 ` Andrii Tseglytskyi
  0 siblings, 1 reply; 69+ messages in thread
From: Stefano Stabellini @ 2014-10-15 10:55 UTC (permalink / raw)
  To: Andrii Tseglytskyi
  Cc: Ian Campbell, Stefano Stabellini, Oleksandr Dmytryshyn,
	Tim Deegan, xen-devel, Stefano Stabellini, Jan Beulich

On Tue, 14 Oct 2014, Andrii Tseglytskyi wrote:
> On Tue, Oct 14, 2014 at 4:05 PM, Ian Campbell <ian.campbell@citrix.com> wrote:
> > On Tue, 2014-10-14 at 16:00 +0300, Andrii Tseglytskyi wrote:
> >> On Tue, Oct 14, 2014 at 3:58 PM, Andrii Tseglytskyi
> >> <andrii.tseglytskyi@globallogic.com> wrote:
> >> > On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
> >> > <stefano.stabellini@eu.citrix.com> wrote:
> >> >> On Tue, 14 Oct 2014, Jan Beulich wrote:
> >> >>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
> >> >>> >> Leaving aside that there are no real context switches between a
> >> >>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
> >> >>> >> get context switched), I'm not sure we need to be worried by these
> >> >>> >> numbers. Whether they're problematic depends significantly on the
> >> >>> >> time a full I2C command takes to issue (and perhaps complete). And
> >> >>> >> then I'm sure you're aware that hypercalls can be batched, so as
> >> >>> >> long as not every of these 50 commands depends on results from
> >> >>> >> the immediately preceding one, the hypercall cost can certainly be
> >> >>> >> amortized to a certain degree.
> >> >>> >
> >> >>> > But in case if each I2C command depends on results of previous one -
> >> >>> > we can't use such calls, right? Can we really rely on this?
> >> >>> > Some time ago I had a model (for testing which is not related to this
> >> >>> > thread) where I sent about 20 hypercalls each second.
> >> >>> > I observed lugs in such use cases as Video playback in domU (Android
> >> >>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
> >> >>> > will be fine and we can send as many hypercalls as we want. But I'm
> >> >>> > worrying in our case this will not work.
> >> >>>
> >> >>> If 20 hypercalls a second are a problem, then I think the device isn't
> >> >>> capable enough in the first place to run a virtualized workload, and
> >> >>> if it's so overloaded it's likely also not really useful to reduce the
> >> >>> CPU frequency (as then you'd end up having even more performance
> >> >>> problems).
> >> >>
> >> >> If we need 20 hypercalls a second by design, I think that we might have
> >> >> a broken design.
> >> >
> >> > Agree.
> >> >
> >> >> One thing is requiring hypercalls for configuration,
> >> >> such us PCI config space accesses, but requiring hypercalls to issue
> >> >> commands to a device is very different.
> >> >> I didn't realize that high performance devices could usually be
> >> >> connected via I2C.
> >> >
> >> > This is a real example of touchscreen driver. Each scroll produces
> >> > about 50 I2C commands. If we decide to scroll all the time (why should
> >> > we limit this possibility?) - we will observe significant lags by this
> >> > design.
> >> >
> >>
> >> Especially with Audio playback in background (which also uses I2C),
> >> and simultaneous request of frequency / voltage change.
> >>
> >
> > Are audio, touchscreen and voltage control all on the same i2c bus /
> > behind the same i2c controller?
> >
> 
> Yes. The same bus and the same controller.
 
Jan and I have been discussing this face to face yesterday (thanks to
LinuxCon being located in Germany this year).

We should keep in mind that actually both approaches can coexist and we
should be able to choose the best one for each platform.

But first we need to understand how much overhead the in-hypervisor
approach would add in real world scenarios.
Could you please provide simple measurements of how long does it take to
make an hypercall on your platform? Use an hypercall that is more
complex that an empty debug call, maybe XENMEM_current_reservation or
HVMOP_get_param?  You can use the arch_timer in the guest to get the
measurements and just post the number of ticks that it takes to complete
the call, together with the clock frequency of the timer.
Also it would be nice to know how many I2C bus accesses per seconds the
drivers on your board actually make. You could take a measurement by
editing your Linux kernel and adding a counter in the I2C subsystem.

Thanks!

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-15 10:55                                               ` Stefano Stabellini
@ 2014-10-15 11:17                                                 ` Andrii Tseglytskyi
  2014-10-15 12:34                                                   ` Ian Campbell
  2014-10-15 16:26                                                   ` Jan Beulich
  0 siblings, 2 replies; 69+ messages in thread
From: Andrii Tseglytskyi @ 2014-10-15 11:17 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

Hi Stefano,

On Wed, Oct 15, 2014 at 1:55 PM, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Tue, 14 Oct 2014, Andrii Tseglytskyi wrote:
>> On Tue, Oct 14, 2014 at 4:05 PM, Ian Campbell <ian.campbell@citrix.com> wrote:
>> > On Tue, 2014-10-14 at 16:00 +0300, Andrii Tseglytskyi wrote:
>> >> On Tue, Oct 14, 2014 at 3:58 PM, Andrii Tseglytskyi
>> >> <andrii.tseglytskyi@globallogic.com> wrote:
>> >> > On Tue, Oct 14, 2014 at 3:51 PM, Stefano Stabellini
>> >> > <stefano.stabellini@eu.citrix.com> wrote:
>> >> >> On Tue, 14 Oct 2014, Jan Beulich wrote:
>> >> >>> >>> On 13.10.14 at 16:29, <andrii.tseglytskyi@globallogic.com> wrote:
>> >> >>> >> Leaving aside that there are no real context switches between a
>> >> >>> >> domain and the hypervisor (only domains, or more precisely vCPU-s,
>> >> >>> >> get context switched), I'm not sure we need to be worried by these
>> >> >>> >> numbers. Whether they're problematic depends significantly on the
>> >> >>> >> time a full I2C command takes to issue (and perhaps complete). And
>> >> >>> >> then I'm sure you're aware that hypercalls can be batched, so as
>> >> >>> >> long as not every of these 50 commands depends on results from
>> >> >>> >> the immediately preceding one, the hypercall cost can certainly be
>> >> >>> >> amortized to a certain degree.
>> >> >>> >
>> >> >>> > But in case if each I2C command depends on results of previous one -
>> >> >>> > we can't use such calls, right? Can we really rely on this?
>> >> >>> > Some time ago I had a model (for testing which is not related to this
>> >> >>> > thread) where I sent about 20 hypercalls each second.
>> >> >>> > I observed lugs in such use cases as Video playback in domU (Android
>> >> >>> > Jelly Bean as domU). Maybe if we have only Xen and dom0 - everything
>> >> >>> > will be fine and we can send as many hypercalls as we want. But I'm
>> >> >>> > worrying in our case this will not work.
>> >> >>>
>> >> >>> If 20 hypercalls a second are a problem, then I think the device isn't
>> >> >>> capable enough in the first place to run a virtualized workload, and
>> >> >>> if it's so overloaded it's likely also not really useful to reduce the
>> >> >>> CPU frequency (as then you'd end up having even more performance
>> >> >>> problems).
>> >> >>
>> >> >> If we need 20 hypercalls a second by design, I think that we might have
>> >> >> a broken design.
>> >> >
>> >> > Agree.
>> >> >
>> >> >> One thing is requiring hypercalls for configuration,
>> >> >> such us PCI config space accesses, but requiring hypercalls to issue
>> >> >> commands to a device is very different.
>> >> >> I didn't realize that high performance devices could usually be
>> >> >> connected via I2C.
>> >> >
>> >> > This is a real example of touchscreen driver. Each scroll produces
>> >> > about 50 I2C commands. If we decide to scroll all the time (why should
>> >> > we limit this possibility?) - we will observe significant lags by this
>> >> > design.
>> >> >
>> >>
>> >> Especially with Audio playback in background (which also uses I2C),
>> >> and simultaneous request of frequency / voltage change.
>> >>
>> >
>> > Are audio, touchscreen and voltage control all on the same i2c bus /
>> > behind the same i2c controller?
>> >
>>
>> Yes. The same bus and the same controller.
>
> Jan and I have been discussing this face to face yesterday (thanks to
> LinuxCon being located in Germany this year).
>
> We should keep in mind that actually both approaches can coexist and we
> should be able to choose the best one for each platform.
>

What if we try to implement both and see which one is better? But I
would prefer to implement solution without I2C in hypervisor frirst ))
And post it as RFC of course.

> But first we need to understand how much overhead the in-hypervisor
> approach would add in real world scenarios.
> Could you please provide simple measurements of how long does it take to
> make an hypercall on your platform? Use an hypercall that is more
> complex that an empty debug call, maybe XENMEM_current_reservation or
> HVMOP_get_param?  You can use the arch_timer in the guest to get the
> measurements and just post the number of ticks that it takes to complete
> the call, together with the clock frequency of the timer.

Some time ago I did measurements of IRQ latency, introduced by
hypervisor, it is pretty similar to what you are suggesting:

http://lists.xen.org/archives/html/xen-devel/2014-08/msg02963.html

> Also it would be nice to know how many I2C bus accesses per seconds the
> drivers on your board actually make. You could take a measurement by
> editing your Linux kernel and adding a counter in the I2C subsystem.
>

IMO - synchronization of I2C access between dom0 and hypervisot will be painful.

Regards,
Andrii




-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-15 11:17                                                 ` Andrii Tseglytskyi
@ 2014-10-15 12:34                                                   ` Ian Campbell
  2014-10-15 16:26                                                   ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-10-15 12:34 UTC (permalink / raw)
  To: Andrii Tseglytskyi
  Cc: Stefano Stabellini, Oleksandr Dmytryshyn, Tim Deegan, xen-devel,
	Stefano Stabellini, Jan Beulich

On Wed, 2014-10-15 at 14:17 +0300, Andrii Tseglytskyi wrote:
> > Jan and I have been discussing this face to face yesterday (thanks to
> > LinuxCon being located in Germany this year).
> >
> > We should keep in mind that actually both approaches can coexist and we
> > should be able to choose the best one for each platform.
> >
> 
> What if we try to implement both and see which one is better? But I
> would prefer to implement solution without I2C in hypervisor frirst ))
> And post it as RFC of course.

My preference would be to implement the in hypervisor based one first
(since this is the architecturally cleaner option) and then only do the
out of hypervisor one if it turns out to be unworkable in practice.

> > Also it would be nice to know how many I2C bus accesses per seconds the
> > drivers on your board actually make. You could take a measurement by
> > editing your Linux kernel and adding a counter in the I2C subsystem.
> >
> 
> IMO - synchronization of I2C access between dom0 and hypervisot will be painful.

I think this supposition needs backing with evidence of the type Stefano
is asking for, or by actually building it and showing it doesn't work on
this particular platform.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver
  2014-10-15 11:17                                                 ` Andrii Tseglytskyi
  2014-10-15 12:34                                                   ` Ian Campbell
@ 2014-10-15 16:26                                                   ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2014-10-15 16:26 UTC (permalink / raw)
  To: stefano.stabellini, andrii.tseglytskyi
  Cc: tim, oleksandr.dmytryshyn, Stefano.Stabellini, ian.campbell, xen-devel

>>> Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com> 10/15/14 1:19 PM >>>
>IMO - synchronization of I2C access between dom0 and hypervisot will be painful.

This heavily depends on the actual model you would choose to do this. E.g.
I don't think synchronization via shared memory would impose that much of
an overhead.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2014-10-15 16:26 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-07 14:19 [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 01/13] cpufreq: move cpufreq.h file to the xen/include/cpufreq location Oleksandr Dmytryshyn
2014-10-07 14:22   ` Andrew Cooper
2014-10-07 14:27     ` Oleksandr Dmytryshyn
2014-10-07 14:35   ` Jan Beulich
2014-10-09  6:04     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 02/13] pm: move processor_perf.h " Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 03/13] pmstat: move pmstat.c file to the xen/drivers/pm location Oleksandr Dmytryshyn
2014-10-07 14:38   ` Jan Beulich
2014-10-09  6:05     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 04/13] cpufreq: use turbo settings only for x86 architecture Oleksandr Dmytryshyn
2014-10-07 14:39   ` Jan Beulich
2014-10-09  6:05     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 05/13] pmstat: make pmstat functions more generalizable Oleksandr Dmytryshyn
2014-10-07 14:40   ` Jan Beulich
2014-10-09  6:06     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 06/13] cpufreq: make cpufreq driver " Oleksandr Dmytryshyn
2014-10-07 14:42   ` Jan Beulich
2014-10-09  6:06     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 07/13] xen/arm: enable cpu hotplug Oleksandr Dmytryshyn
2014-10-07 15:15   ` Julien Grall
2014-10-09  6:07     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 08/13] xen/dts: make the dt_find_property function to be global Oleksandr Dmytryshyn
2014-10-07 15:09   ` Julien Grall
2014-10-09  6:09     ` Oleksandr Dmytryshyn
2014-10-09 11:15       ` Julien Grall
2014-10-09 11:40         ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 09/13] arch/arm: create device tree nodes for Dom0 cpufreq cpu driver Oleksandr Dmytryshyn
2014-10-07 15:26   ` Julien Grall
2014-10-09  6:10     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 10/13] xen: arm: implement platform hypercall Oleksandr Dmytryshyn
2014-10-07 15:39   ` Julien Grall
2014-10-09  6:11     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 11/13] cpufreq: add xen-cpufreq driver Oleksandr Dmytryshyn
2014-10-07 14:44   ` Jan Beulich
2014-10-08 13:51     ` Stefano Stabellini
2014-10-10  9:00       ` Jan Beulich
2014-10-10  9:04         ` Stefano Stabellini
2014-10-10  9:39       ` Jan Beulich
2014-10-10  9:39         ` Stefano Stabellini
2014-10-10  9:46           ` Jan Beulich
2014-10-10  9:54             ` Stefano Stabellini
2014-10-10  9:59               ` Ian Campbell
2014-10-10 12:51                 ` Jan Beulich
2014-10-10 14:42                   ` Stefano Stabellini
2014-10-13  8:56                     ` Oleksandr Dmytryshyn
2014-10-13  9:39                       ` Jan Beulich
2014-10-13 11:59                         ` Oleksandr Dmytryshyn
2014-10-13 12:28                           ` Jan Beulich
2014-10-13 13:38                             ` Andrii Tseglytskyi
2014-10-13 14:11                               ` Jan Beulich
2014-10-13 14:29                                 ` Andrii Tseglytskyi
2014-10-14 12:20                                   ` Jan Beulich
2014-10-14 12:39                                     ` Andrii Tseglytskyi
2014-10-14 12:51                                     ` Stefano Stabellini
2014-10-14 12:58                                       ` Andrii Tseglytskyi
2014-10-14 13:00                                         ` Andrii Tseglytskyi
2014-10-14 13:05                                           ` Ian Campbell
2014-10-14 13:07                                             ` Andrii Tseglytskyi
2014-10-15 10:55                                               ` Stefano Stabellini
2014-10-15 11:17                                                 ` Andrii Tseglytskyi
2014-10-15 12:34                                                   ` Ian Campbell
2014-10-15 16:26                                                   ` Jan Beulich
2014-10-10 15:19                   ` Ian Campbell
2014-10-10 10:40               ` Jan Beulich
2014-10-09  6:13     ` Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 12/13] xen: arm: implement XEN_SYSCTL_cpufreq_op Oleksandr Dmytryshyn
2014-10-07 14:19 ` [RFC PATCH 13/13] xen/arm: enable cpufreq functionality for ARM Oleksandr Dmytryshyn
2014-10-07 14:34 ` [RFC PATCH 00/13] xen_cpufreq implementation in Xen hypervisor Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.