diff mbox

[v4,7/9] KVM-GST: KVM Steal time accounting

Message ID 1309555369-16867-8-git-send-email-glommer@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Glauber Costa July 1, 2011, 9:22 p.m. UTC
This patch accounts steal time time in account_process_tick.
If one or more tick is considered stolen in the current
accounting cycle, user/system accounting is skipped. Idle is fine,
since the hypervisor does not report steal time if the guest
is halted.

Accounting steal time from the core scheduler give us the
advantage of direct access to the runqueue data. In a later
opportunity, it can be used to tweak cpu power and make
the scheduler aware of the time it lost.

Signed-off-by: Glauber Costa <glommer@redhat.com>
CC: Rik van Riel <riel@redhat.com>
CC: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Avi Kivity <avi@redhat.com>
CC: Anthony Liguori <aliguori@us.ibm.com>
CC: Eric B Munson <emunson@mgebm.net>
---
 kernel/sched.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

Comments

Peter Zijlstra July 2, 2011, 10:30 a.m. UTC | #1
On Fri, 2011-07-01 at 17:22 -0400, Glauber Costa wrote:
> @@ -3929,6 +3945,23 @@ void account_process_tick(struct task_struct *p, int user_tick)
>                 return;
>         }
>  
> +#ifdef CONFIG_PARAVIRT
> +       if (static_branch(&paravirt_steal_enabled)) {
> +               u64 steal, st = 0;
> +
> +               steal = paravirt_steal_clock(smp_processor_id());
> +               steal -= this_rq()->prev_steal_time;
> +
> +               st = steal_ticks(steal);
> +               this_rq()->prev_steal_time += st * TICK_NSEC;
> +
> +               if (st) {
> +                       account_steal_time(st);
> +                       return;
> +               }
> +       }
> +#endif
> +
>         if (user_tick)
>                 account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
>         else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) 

So I was about to send an Ack for this patch, when I noticed that this
will all be dead code when CONFIG_IRQ_TIME_ACCOUNTING &&
sched_clock_irqtime.

I think irqtime_account_process_tick() wants a similar hunk (which
suggests splitting it out into an inline function).
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/kernel/sched.c b/kernel/sched.c
index 3f2e502..247dd51 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -75,6 +75,7 @@ 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
 #include <asm/mutex.h>
+#include <asm/paravirt.h>
 
 #include "sched_cpupri.h"
 #include "workqueue_sched.h"
@@ -528,6 +529,9 @@  struct rq {
 #ifdef CONFIG_IRQ_TIME_ACCOUNTING
 	u64 prev_irq_time;
 #endif
+#ifdef CONFIG_PARAVIRT
+	u64 prev_steal_time;
+#endif
 
 	/* calc_load related fields */
 	unsigned long calc_load_update;
@@ -1953,6 +1957,18 @@  void account_system_vtime(struct task_struct *curr)
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
 
+#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
+
+#ifdef CONFIG_PARAVIRT
+static inline u64 steal_ticks(u64 steal)
+{
+	if (unlikely(steal > NSEC_PER_SEC))
+		return div_u64(steal, TICK_NSEC);
+
+	return __iter_div_u64_rem(steal, TICK_NSEC, &steal);
+}
+#endif
+
 static void update_rq_clock_task(struct rq *rq, s64 delta)
 {
 	s64 irq_delta;
@@ -3929,6 +3945,23 @@  void account_process_tick(struct task_struct *p, int user_tick)
 		return;
 	}
 
+#ifdef CONFIG_PARAVIRT
+	if (static_branch(&paravirt_steal_enabled)) {
+		u64 steal, st = 0;
+
+		steal = paravirt_steal_clock(smp_processor_id());
+		steal -= this_rq()->prev_steal_time;
+
+		st = steal_ticks(steal);
+		this_rq()->prev_steal_time += st * TICK_NSEC;
+
+		if (st) {
+			account_steal_time(st);
+			return;
+		}
+	}
+#endif
+
 	if (user_tick)
 		account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
 	else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET))