@@ -302,6 +302,7 @@ long io_schedule_timeout(long timeout);
extern void cpu_init (void);
extern void trap_init(void);
extern void update_process_times(int user);
+extern cputime_t (*hypervisor_steal_time)(void);
extern void scheduler_tick(void);
extern void sched_show_task(struct task_struct *p);
@@ -501,6 +501,8 @@ struct rq {
struct sched_domain *sd;
unsigned long cpu_power;
+ unsigned long real_ticks;
+ unsigned long total_ticks;
unsigned char idle_at_tick;
/* For active balancing */
@@ -3533,10 +3535,12 @@ static int touch_steal_time(int is_idle)
if (is_idle)
return 0;
+ rq->total_ticks++;
if (steal) {
account_steal_time(steal);
return 1;
}
+ rq->real_ticks++;
return 0;
}
@@ -2509,6 +2509,16 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
power >>= SCHED_LOAD_SHIFT;
}
+ WARN_ON(cpu_rq(cpu)->real_ticks > cpu_rq(cpu)->total_ticks);
+
+ if (cpu_rq(cpu)->total_ticks) {
+ power *= cpu_rq(cpu)->real_ticks;
+ power /= cpu_rq(cpu)->total_ticks;
+ }
+
+ cpu_rq(cpu)->total_ticks = 0;
+ cpu_rq(cpu)->real_ticks = 0;
+
sdg->cpu_power_orig = power;
if (sched_feat(ARCH_POWER))