diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2009-03-04 13:05:41 +0100 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-03-26 18:50:51 +0100 |
commit | 1aec1c558a797512e922581b21a178a05438bfc9 (patch) | |
tree | ad5fb128e3dc4a6575bdf61534c2bf314ea1d094 /arch/ia64/xen/time.c | |
parent | ia64/pv_ops/pv_time_ops: add sched_clock hook. (diff) | |
download | linux-1aec1c558a797512e922581b21a178a05438bfc9.tar.xz linux-1aec1c558a797512e922581b21a178a05438bfc9.zip |
ia64/pv_ops/xen/pv_time_ops: implement sched_clock.
paravirtualize sched_clock.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/xen/time.c')
-rw-r--r-- | arch/ia64/xen/time.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c index 68d6204c3f16..fb8332690179 100644 --- a/arch/ia64/xen/time.c +++ b/arch/ia64/xen/time.c @@ -175,10 +175,58 @@ static void xen_itc_jitter_data_reset(void) } while (unlikely(ret != lcycle)); } +/* based on xen_sched_clock() in arch/x86/xen/time.c. */ +/* + * This relies on HAVE_UNSTABLE_SCHED_CLOCK. If it can't be defined, + * something similar logic should be implemented here. + */ +/* + * Xen sched_clock implementation. Returns the number of unstolen + * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED + * states. + */ +static unsigned long long xen_sched_clock(void) +{ + struct vcpu_runstate_info runstate; + + unsigned long long now; + unsigned long long offset; + unsigned long long ret; + + /* + * Ideally sched_clock should be called on a per-cpu basis + * anyway, so preempt should already be disabled, but that's + * not current practice at the moment. + */ + preempt_disable(); + + /* + * both ia64_native_sched_clock() and xen's runstate are + * based on mAR.ITC. So difference of them makes sense. + */ + now = ia64_native_sched_clock(); + + get_runstate_snapshot(&runstate); + + WARN_ON(runstate.state != RUNSTATE_running); + + offset = 0; + if (now > runstate.state_entry_time) + offset = now - runstate.state_entry_time; + ret = runstate.time[RUNSTATE_blocked] + + runstate.time[RUNSTATE_running] + + offset; + + preempt_enable(); + + return ret; +} + struct pv_time_ops xen_time_ops __initdata = { .init_missing_ticks_accounting = xen_init_missing_ticks_accounting, .do_steal_accounting = xen_do_steal_accounting, .clocksource_resume = xen_itc_jitter_data_reset, + .sched_clock = xen_sched_clock, }; /* Called after suspend, to resume time. */ |