[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC 2/6] schedule: account true system idle time



From: Andrii Anisov <andrii_anisov@xxxxxxxx>

Currently the idle time is being accounted as a idle vcpu runtime.
This is not entirely correct, because the entity named idle vcpu is
in fact a hypervisor tasks worker. E.g. some softirqs are processed
by the idle vcpu.
So lets change idle vcpu time accounting and specify system idle time
as a idle vcpu blocked time. For this we should appropriately change
idle vcpu runstates around the real processor idle entry.

Signed-off-by: Andrii Anisov <andrii_anisov@xxxxxxxx>
---
 xen/arch/arm/domain.c | 24 ++++++++++++++++++++++++
 xen/common/schedule.c |  4 +++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 941bbff..a4e0fd7 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -19,6 +19,7 @@
 #include <xen/sched.h>
 #include <xen/softirq.h>
 #include <xen/wait.h>
+#include <xen/sched-if.h>
 
 #include <asm/alternative.h>
 #include <asm/cpuerrata.h>
@@ -42,6 +43,27 @@
 
 DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
 
+static inline void idle_vcpu_runstate_change(
+    unsigned int cpu, int new_state, s_time_t new_entry_time)
+{
+    s_time_t delta;
+    struct vcpu *v = idle_vcpu[cpu];
+    spinlock_t *lock = vcpu_schedule_lock(v);
+
+    ASSERT(v == current);
+    ASSERT(v->runstate.state != new_state);
+
+    delta = new_entry_time - v->runstate.state_entry_time;
+    if ( delta > 0 )
+    {
+        v->runstate.time[v->runstate.state] += delta;
+        v->runstate.state_entry_time = new_entry_time;
+    }
+
+    v->runstate.state = new_state;
+    vcpu_schedule_unlock(lock, v);
+}
+
 static void do_idle(void)
 {
     unsigned int cpu = smp_processor_id();
@@ -51,11 +73,13 @@ static void do_idle(void)
     process_pending_softirqs();
 
     local_irq_disable();
+    idle_vcpu_runstate_change(cpu, RUNSTATE_blocked, NOW());
     if ( cpu_is_haltable(cpu) )
     {
         dsb(sy);
         wfi();
     }
+    idle_vcpu_runstate_change(cpu, RUNSTATE_running, NOW());
     local_irq_enable();
 
     sched_tick_resume();
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 349f962..0a38d4a 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -214,7 +214,7 @@ uint64_t get_cpu_idle_time(unsigned int cpu)
     if ( cpu_online(cpu) && v )
         vcpu_runstate_get(v, &state);
 
-    return state.time[RUNSTATE_running];
+    return state.time[RUNSTATE_blocked];
 }
 
 /*
@@ -922,6 +922,8 @@ void vcpu_block(void)
 {
     struct vcpu *v = current;
 
+    ASSERT(!is_idle_vcpu(v));
+
     set_bit(_VPF_blocked, &v->pause_flags);
 
     arch_vcpu_block(v);
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.