diff options
author | Jeremy Fitzhardinge <jeremy@xensource.com> | 2007-07-17 18:37:05 -0700 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-07-18 08:47:43 -0700 |
commit | ab55028886dd1dd54585f22bf19a00eb23869340 (patch) | |
tree | 083c0c3603242c3794eb9396342a590cf920a8b8 /arch | |
parent | f91a8b447b9af64f589f6e13fec7f09b5927563d (diff) |
xen: Implement sched_clock
Implement xen_sched_clock, which returns the number of ns the current
vcpu has been actually in an unstolen state (ie, running or blocked,
vs runnable-but-not-running, or offline) since boot.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Acked-by: Chris Wright <chrisw@sous-sol.org>
Cc: john stultz <johnstul@us.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/xen/enlighten.c | 2 | ||||
-rw-r--r-- | arch/i386/xen/time.c | 27 | ||||
-rw-r--r-- | arch/i386/xen/xen-ops.h | 3 |
3 files changed, 28 insertions, 4 deletions
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 9550ae3b1fb..a9ba834295a 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c @@ -683,7 +683,7 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = { .set_wallclock = xen_set_wallclock, .get_wallclock = xen_get_wallclock, .get_cpu_khz = xen_cpu_khz, - .sched_clock = xen_clocksource_read, + .sched_clock = xen_sched_clock, .cpuid = xen_cpuid, diff --git a/arch/i386/xen/time.c b/arch/i386/xen/time.c index acbfd996946..2aab44bec2a 100644 --- a/arch/i386/xen/time.c +++ b/arch/i386/xen/time.c @@ -28,6 +28,8 @@ #define TIMER_SLOP 100000 #define NS_PER_TICK (1000000000LL / HZ) +static cycle_t xen_clocksource_read(void); + /* These are perodically updated in shared_info, and then copied here. */ struct shadow_time_info { u64 tsc_timestamp; /* TSC at last update of time vals. */ @@ -169,6 +171,29 @@ static void do_stolen_accounting(void) account_steal_time(idle_task(smp_processor_id()), ticks); } +/* + * Xen sched_clock implementation. Returns the number of unstolen + * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED + * states. + */ +unsigned long long xen_sched_clock(void) +{ + struct vcpu_runstate_info state; + cycle_t now = xen_clocksource_read(); + s64 offset; + + get_runstate_snapshot(&state); + + WARN_ON(state.state != RUNSTATE_running); + + offset = now - state.state_entry_time; + if (offset < 0) + offset = 0; + + return state.time[RUNSTATE_blocked] + + state.time[RUNSTATE_running] + + offset; +} /* Get the CPU speed from Xen */ @@ -261,7 +286,7 @@ static u64 get_nsec_offset(struct shadow_time_info *shadow) return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift); } -cycle_t xen_clocksource_read(void) +static cycle_t xen_clocksource_read(void) { struct shadow_time_info *shadow = &get_cpu_var(shadow_time); cycle_t ret; diff --git a/arch/i386/xen/xen-ops.h b/arch/i386/xen/xen-ops.h index 54d98b52085..7667abd390e 100644 --- a/arch/i386/xen/xen-ops.h +++ b/arch/i386/xen/xen-ops.h @@ -2,7 +2,6 @@ #define XEN_OPS_H #include <linux/init.h> -#include <linux/clocksource.h> DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); DECLARE_PER_CPU(unsigned long, xen_cr3); @@ -18,7 +17,7 @@ unsigned long xen_cpu_khz(void); void __init xen_time_init(void); unsigned long xen_get_wallclock(void); int xen_set_wallclock(unsigned long time); -cycle_t xen_clocksource_read(void); +unsigned long long xen_sched_clock(void); void xen_mark_init_mm_pinned(void); |