Skip to content

Commit

Permalink
context_tracing: Fix guest accounting with native vtime
Browse files Browse the repository at this point in the history
1) If context tracking is enabled with native vtime accounting (which
combo is useless except for dev testing), we call vtime_guest_enter()
and vtime_guest_exit() on host <-> guest switches. But those are stubs
in this configurations. As a result, cputime is not correctly flushed
on kvm context switches.

2) If context tracking runs but is disabled on some CPUs, those
CPUs end up calling __guest_enter/__guest_exit which in turn
call vtime_account_system(). We don't want to call this because we
run in tick based accounting for these CPUs.

Refactor the guest_enter/guest_exit code such that all combinations
finally work.

Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Li Zhong <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Kevin Hilman <[email protected]>
  • Loading branch information
fweisbec committed Aug 12, 2013
1 parent fbb00b5 commit 2d854e5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 32 deletions.
52 changes: 22 additions & 30 deletions include/linux/context_tracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,6 @@ struct context_tracking {
} state;
};

static inline void __guest_enter(void)
{
/*
* This is running in ioctl context so we can avoid
* the call to vtime_account() with its unnecessary idle check.
*/
vtime_account_system(current);
current->flags |= PF_VCPU;
}

static inline void __guest_exit(void)
{
/*
* This is running in ioctl context so we can avoid
* the call to vtime_account() with its unnecessary idle check.
*/
vtime_account_system(current);
current->flags &= ~PF_VCPU;
}

#ifdef CONFIG_CONTEXT_TRACKING
DECLARE_PER_CPU(struct context_tracking, context_tracking);
Expand All @@ -56,9 +37,6 @@ static inline bool context_tracking_active(void)
extern void user_enter(void);
extern void user_exit(void);

extern void guest_enter(void);
extern void guest_exit(void);

static inline enum ctx_state exception_enter(void)
{
enum ctx_state prev_ctx;
Expand All @@ -81,21 +59,35 @@ extern void context_tracking_task_switch(struct task_struct *prev,
static inline bool context_tracking_in_user(void) { return false; }
static inline void user_enter(void) { }
static inline void user_exit(void) { }
static inline enum ctx_state exception_enter(void) { return 0; }
static inline void exception_exit(enum ctx_state prev_ctx) { }
static inline void context_tracking_task_switch(struct task_struct *prev,
struct task_struct *next) { }
#endif /* !CONFIG_CONTEXT_TRACKING */

#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
extern void guest_enter(void);
extern void guest_exit(void);
#else
static inline void guest_enter(void)
{
__guest_enter();
/*
* This is running in ioctl context so we can avoid
* the call to vtime_account() with its unnecessary idle check.
*/
vtime_account_system(current);
current->flags |= PF_VCPU;
}

static inline void guest_exit(void)
{
__guest_exit();
/*
* This is running in ioctl context so we can avoid
* the call to vtime_account() with its unnecessary idle check.
*/
vtime_account_system(current);
current->flags &= ~PF_VCPU;
}

static inline enum ctx_state exception_enter(void) { return 0; }
static inline void exception_exit(enum ctx_state prev_ctx) { }
static inline void context_tracking_task_switch(struct task_struct *prev,
struct task_struct *next) { }
#endif /* !CONFIG_CONTEXT_TRACKING */
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */

#endif
6 changes: 4 additions & 2 deletions kernel/context_tracking.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ void user_exit(void)
local_irq_restore(flags);
}

#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
void guest_enter(void)
{
if (vtime_accounting_enabled())
vtime_guest_enter(current);
else
__guest_enter();
current->flags |= PF_VCPU;
}
EXPORT_SYMBOL_GPL(guest_enter);

Expand All @@ -155,9 +156,10 @@ void guest_exit(void)
if (vtime_accounting_enabled())
vtime_guest_exit(current);
else
__guest_exit();
current->flags &= ~PF_VCPU;
}
EXPORT_SYMBOL_GPL(guest_exit);
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */


/**
Expand Down

0 comments on commit 2d854e5

Please sign in to comment.