Modify the cpufreq ondemand governor so that it can get idle and
total ticks from the Xen hypervisor. Linux and Xen have different
ideas of what an idle tick is, so the Xen values for both have to
be returned in the same platform hypercall. Otherwise, use
basically the same scheme as native Linux.
Signed-off-by: Mark Langsdorf <mark.langsdorf@xxxxxxx>
iff -r 9bf1ddd0f6bf drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c Wed Oct 17 09:24:03 2007 +0100
+++ b/drivers/cpufreq/cpufreq_ondemand.c Thu Oct 18 16:08:36 2007 -0500
@@ -221,18 +222,14 @@ static struct attribute_group dbs_attr_g
};
/************************** sysfs end ************************/
-
-static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
-{
- unsigned int idle_ticks, total_ticks;
- unsigned int load;
+#ifndef CONFIG_XEN
+static int dbs_calc_load(struct cpu_dbs_info_s *this_dbs_info)
+{
+ struct cpufreq_policy *policy;
cputime64_t cur_jiffies;
-
- struct cpufreq_policy *policy;
+ cputime64_t total_ticks, idle_ticks;
unsigned int j;
-
- if (!this_dbs_info->enable)
- return;
+ int load;
policy = this_dbs_info->cur_policy;
cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
@@ -240,7 +237,7 @@ static void dbs_check_cpu(struct cpu_dbs
this_dbs_info->prev_cpu_wall);
this_dbs_info->prev_cpu_wall = cur_jiffies;
if (!total_ticks)
- return;
+ return 200;
/*
* Every sampling_rate, we check, if current idle time is less
* than 20% (default), then we try to increase frequency
@@ -270,6 +267,67 @@ static void dbs_check_cpu(struct cpu_dbs
idle_ticks = tmp_idle_ticks;
}
load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+ return load;
+}
+#else
+
+#include <xen/interface/platform.h>
+static int dbs_calc_load(struct cpu_dbs_info_s *this_dbs_info)
+{
+ int load = 0;
+ struct xen_platform_op op;
+ uint64_t idletime[NR_CPUS];
+ uint64_t totaltime[NR_CPUS];
+ struct cpufreq_policy *policy;
+ unsigned int j;
+
+ op.cmd = XENPF_getidletime;
+ op.u.getidletime.max_cpus = num_online_cpus();
+ set_xen_guest_handle(op.u.getidletime.idletime, idletime);
+ set_xen_guest_handle(op.u.getidletime.totaltime, totaltime);
+ HYPERVISOR_platform_op(&op);
+
+ policy = this_dbs_info->cur_policy;
+ for_each_cpu_mask(j, policy->cpus) {
+ cputime64_t total_idle_ticks, total_wall_ticks;
+ cputime64_t tmp_idle_ticks, tmp_wall_ticks;
+ struct cpu_dbs_info_s *j_dbs_info;
+ unsigned long tmp_load;
+
+ j_dbs_info = &per_cpu(cpu_dbs_info, j);
+ total_idle_ticks = idletime[j];
+ tmp_idle_ticks = cputime64_sub(total_idle_ticks,
+ j_dbs_info->prev_cpu_idle);
+ total_wall_ticks = totaltime[j];
+ tmp_wall_ticks = cputime64_sub(total_wall_ticks,
+ j_dbs_info->prev_cpu_wall);
+ if (tmp_wall_ticks == 0)
+ return 200;
+
+ j_dbs_info->prev_cpu_wall = total_wall_ticks;
+ j_dbs_info->prev_cpu_idle = total_idle_ticks;
+
+ tmp_load = (100 * (tmp_wall_ticks - tmp_idle_ticks)) /
+ tmp_wall_ticks;
+ load = max(load, min(100, (int) tmp_load));
+ }
+ return load;
+}
+#endif
+
+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+{
+ int load;
+
+ struct cpufreq_policy *policy;
+
+ if (!this_dbs_info->enable)
+ return;
+
+ policy = this_dbs_info->cur_policy;
+ load = dbs_calc_load(this_dbs_info);
+ if (load > 100)
+ return;
/* Check for frequency increase */
if (load > dbs_tuners_ins.up_threshold) {
diff -r 9bf1ddd0f6bf include/xen/interface/platform.h
--- a/include/xen/interface/platform.h Wed Oct 17 09:24:03 2007 +0100
+++ b/include/xen/interface/platform.h Thu Oct 18 16:08:36 2007 -0500
@@ -179,6 +179,7 @@ struct xenpf_getidletime {
/* IN variables. */
uint32_t max_cpus;
XEN_GUEST_HANDLE(uint64_t) idletime;
+ XEN_GUEST_HANDLE(uint64_t) totaltime;
/* OUT variables. */
uint32_t nr_cpus;
};
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|