aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-01-20 18:50:22 -0500
committerFrederic Weisbecker <fweisbec@gmail.com>2013-01-27 14:35:40 -0500
commitc11f11fcbdb5be790c565aed46411486a7586afc (patch)
tree56552d483192df72e9c2bbb4c3b976ba05740626
parent6fac4829ce0ef9b7f24369086ce5f0e9f38d37bc (diff)
kvm: Prepare to add generic guest entry/exit callbacks
Do some ground preparatory work before adding guest_enter() and guest_exit() context tracking callbacks. Those will be later used to read the guest cputime safely when we run in full dynticks mode. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Gleb Natapov <gleb@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Li Zhong <zhong@linux.vnet.ibm.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/ia64/kernel/time.c1
-rw-r--r--arch/powerpc/kernel/time.c1
-rw-r--r--include/linux/kvm_host.h39
-rw-r--r--include/linux/vtime.h2
-rw-r--r--kernel/sched/cputime.c10
5 files changed, 32 insertions, 21 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index a3a3f5a1cb3a..fbaac1afb844 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -136,6 +136,7 @@ void vtime_account_system(struct task_struct *tsk)
136 136
137 account_system_time(tsk, 0, delta, delta); 137 account_system_time(tsk, 0, delta, delta);
138} 138}
139EXPORT_SYMBOL_GPL(vtime_account_system);
139 140
140void vtime_account_idle(struct task_struct *tsk) 141void vtime_account_idle(struct task_struct *tsk)
141{ 142{
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 22c9b67f9983..2e04b37f67f9 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -347,6 +347,7 @@ void vtime_account_system(struct task_struct *tsk)
347 if (stolen) 347 if (stolen)
348 account_steal_time(stolen); 348 account_steal_time(stolen);
349} 349}
350EXPORT_SYMBOL_GPL(vtime_account_system);
350 351
351void vtime_account_idle(struct task_struct *tsk) 352void vtime_account_idle(struct task_struct *tsk)
352{ 353{
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2c497ab0d03d..4fe2396401da 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -22,6 +22,7 @@
22#include <linux/rcupdate.h> 22#include <linux/rcupdate.h>
23#include <linux/ratelimit.h> 23#include <linux/ratelimit.h>
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/irqflags.h>
25#include <asm/signal.h> 26#include <asm/signal.h>
26 27
27#include <linux/kvm.h> 28#include <linux/kvm.h>
@@ -740,15 +741,36 @@ static inline int kvm_deassign_device(struct kvm *kvm,
740} 741}
741#endif /* CONFIG_IOMMU_API */ 742#endif /* CONFIG_IOMMU_API */
742 743
743static inline void kvm_guest_enter(void) 744static inline void guest_enter(void)
744{ 745{
745 BUG_ON(preemptible());
746 /* 746 /*
747 * This is running in ioctl context so we can avoid 747 * This is running in ioctl context so we can avoid
748 * the call to vtime_account() with its unnecessary idle check. 748 * the call to vtime_account() with its unnecessary idle check.
749 */ 749 */
750 vtime_account_system_irqsafe(current); 750 vtime_account_system(current);
751 current->flags |= PF_VCPU; 751 current->flags |= PF_VCPU;
752}
753
754static inline void guest_exit(void)
755{
756 /*
757 * This is running in ioctl context so we can avoid
758 * the call to vtime_account() with its unnecessary idle check.
759 */
760 vtime_account_system(current);
761 current->flags &= ~PF_VCPU;
762}
763
764static inline void kvm_guest_enter(void)
765{
766 unsigned long flags;
767
768 BUG_ON(preemptible());
769
770 local_irq_save(flags);
771 guest_enter();
772 local_irq_restore(flags);
773
752 /* KVM does not hold any references to rcu protected data when it 774 /* KVM does not hold any references to rcu protected data when it
753 * switches CPU into a guest mode. In fact switching to a guest mode 775 * switches CPU into a guest mode. In fact switching to a guest mode
754 * is very similar to exiting to userspase from rcu point of view. In 776 * is very similar to exiting to userspase from rcu point of view. In
@@ -761,12 +783,11 @@ static inline void kvm_guest_enter(void)
761 783
762static inline void kvm_guest_exit(void) 784static inline void kvm_guest_exit(void)
763{ 785{
764 /* 786 unsigned long flags;
765 * This is running in ioctl context so we can avoid 787
766 * the call to vtime_account() with its unnecessary idle check. 788 local_irq_save(flags);
767 */ 789 guest_exit();
768 vtime_account_system_irqsafe(current); 790 local_irq_restore(flags);
769 current->flags &= ~PF_VCPU;
770} 791}
771 792
772/* 793/*
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index 5368af9bdf06..bb50c3ca0d79 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -6,7 +6,6 @@ struct task_struct;
6#ifdef CONFIG_VIRT_CPU_ACCOUNTING 6#ifdef CONFIG_VIRT_CPU_ACCOUNTING
7extern void vtime_task_switch(struct task_struct *prev); 7extern void vtime_task_switch(struct task_struct *prev);
8extern void vtime_account_system(struct task_struct *tsk); 8extern void vtime_account_system(struct task_struct *tsk);
9extern void vtime_account_system_irqsafe(struct task_struct *tsk);
10extern void vtime_account_idle(struct task_struct *tsk); 9extern void vtime_account_idle(struct task_struct *tsk);
11extern void vtime_account_user(struct task_struct *tsk); 10extern void vtime_account_user(struct task_struct *tsk);
12extern void vtime_account(struct task_struct *tsk); 11extern void vtime_account(struct task_struct *tsk);
@@ -20,7 +19,6 @@ static inline bool vtime_accounting_enabled(void) { return true; }
20#else /* !CONFIG_VIRT_CPU_ACCOUNTING */ 19#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
21static inline void vtime_task_switch(struct task_struct *prev) { } 20static inline void vtime_task_switch(struct task_struct *prev) { }
22static inline void vtime_account_system(struct task_struct *tsk) { } 21static inline void vtime_account_system(struct task_struct *tsk) { }
23static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { }
24static inline void vtime_account_user(struct task_struct *tsk) { } 22static inline void vtime_account_user(struct task_struct *tsk) { }
25static inline void vtime_account(struct task_struct *tsk) { } 23static inline void vtime_account(struct task_struct *tsk) { }
26static inline bool vtime_accounting_enabled(void) { return false; } 24static inline bool vtime_accounting_enabled(void) { return false; }
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index c533deaf06d5..a44ecdf809a1 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -465,16 +465,6 @@ void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime
465 *st = cputime.stime; 465 *st = cputime.stime;
466} 466}
467 467
468void vtime_account_system_irqsafe(struct task_struct *tsk)
469{
470 unsigned long flags;
471
472 local_irq_save(flags);
473 vtime_account_system(tsk);
474 local_irq_restore(flags);
475}
476EXPORT_SYMBOL_GPL(vtime_account_system_irqsafe);
477
478#ifndef __ARCH_HAS_VTIME_TASK_SWITCH 468#ifndef __ARCH_HAS_VTIME_TASK_SWITCH
479void vtime_task_switch(struct task_struct *prev) 469void vtime_task_switch(struct task_struct *prev)
480{ 470{