Commit ab550288 authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Jeremy Fitzhardinge

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: default avatarJeremy Fitzhardinge <jeremy@xensource.com>
Acked-by: default avatarChris Wright <chrisw@sous-sol.org>
Cc: john stultz <johnstul@us.ibm.com>
parent f91a8b44
...@@ -683,7 +683,7 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = { ...@@ -683,7 +683,7 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.set_wallclock = xen_set_wallclock, .set_wallclock = xen_set_wallclock,
.get_wallclock = xen_get_wallclock, .get_wallclock = xen_get_wallclock,
.get_cpu_khz = xen_cpu_khz, .get_cpu_khz = xen_cpu_khz,
.sched_clock = xen_clocksource_read, .sched_clock = xen_sched_clock,
.cpuid = xen_cpuid, .cpuid = xen_cpuid,
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#define TIMER_SLOP 100000 #define TIMER_SLOP 100000
#define NS_PER_TICK (1000000000LL / HZ) #define NS_PER_TICK (1000000000LL / HZ)
static cycle_t xen_clocksource_read(void);
/* These are perodically updated in shared_info, and then copied here. */ /* These are perodically updated in shared_info, and then copied here. */
struct shadow_time_info { struct shadow_time_info {
u64 tsc_timestamp; /* TSC at last update of time vals. */ u64 tsc_timestamp; /* TSC at last update of time vals. */
...@@ -169,6 +171,29 @@ static void do_stolen_accounting(void) ...@@ -169,6 +171,29 @@ static void do_stolen_accounting(void)
account_steal_time(idle_task(smp_processor_id()), ticks); 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 */ /* Get the CPU speed from Xen */
...@@ -261,7 +286,7 @@ static u64 get_nsec_offset(struct shadow_time_info *shadow) ...@@ -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); 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); struct shadow_time_info *shadow = &get_cpu_var(shadow_time);
cycle_t ret; cycle_t ret;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define XEN_OPS_H #define XEN_OPS_H
#include <linux/init.h> #include <linux/init.h>
#include <linux/clocksource.h>
DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
DECLARE_PER_CPU(unsigned long, xen_cr3); DECLARE_PER_CPU(unsigned long, xen_cr3);
...@@ -18,7 +17,7 @@ unsigned long xen_cpu_khz(void); ...@@ -18,7 +17,7 @@ unsigned long xen_cpu_khz(void);
void __init xen_time_init(void); void __init xen_time_init(void);
unsigned long xen_get_wallclock(void); unsigned long xen_get_wallclock(void);
int xen_set_wallclock(unsigned long time); 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); void xen_mark_init_mm_pinned(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment