diff options
author | Juergen Gross <jgross@suse.com> | 2016-07-06 01:00:30 -0400 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2016-07-06 05:42:19 -0400 |
commit | 6ba286ad845799b135e5af73d1fbc838fa79f709 (patch) | |
tree | eaa9dae091db425accdda28347ee131b459ab5e3 | |
parent | 4b5ae0150f29f494427a5d5561f1cd43e6cb2396 (diff) |
xen: support runqueue steal time on xen
Up to now reading the stolen time of a remote cpu was not possible in a
performant way under Xen. This made support of runqueue steal time via
paravirt_steal_rq_enabled impossible.
With the addition of an appropriate hypervisor interface this is now
possible, so add the support.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
-rw-r--r-- | drivers/xen/time.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/xen/time.c b/drivers/xen/time.c index 2257b6663766..a7fe35b58341 100644 --- a/drivers/xen/time.c +++ b/drivers/xen/time.c | |||
@@ -47,27 +47,31 @@ static u64 get64(const u64 *p) | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | /* | 50 | static void xen_get_runstate_snapshot_cpu(struct vcpu_runstate_info *res, |
51 | * Runstate accounting | 51 | unsigned int cpu) |
52 | */ | ||
53 | void xen_get_runstate_snapshot(struct vcpu_runstate_info *res) | ||
54 | { | 52 | { |
55 | u64 state_time; | 53 | u64 state_time; |
56 | struct vcpu_runstate_info *state; | 54 | struct vcpu_runstate_info *state; |
57 | 55 | ||
58 | BUG_ON(preemptible()); | 56 | BUG_ON(preemptible()); |
59 | 57 | ||
60 | state = this_cpu_ptr(&xen_runstate); | 58 | state = per_cpu_ptr(&xen_runstate, cpu); |
61 | 59 | ||
62 | /* | ||
63 | * The runstate info is always updated by the hypervisor on | ||
64 | * the current CPU, so there's no need to use anything | ||
65 | * stronger than a compiler barrier when fetching it. | ||
66 | */ | ||
67 | do { | 60 | do { |
68 | state_time = get64(&state->state_entry_time); | 61 | state_time = get64(&state->state_entry_time); |
62 | rmb(); /* Hypervisor might update data. */ | ||
69 | *res = READ_ONCE(*state); | 63 | *res = READ_ONCE(*state); |
70 | } while (get64(&state->state_entry_time) != state_time); | 64 | rmb(); /* Hypervisor might update data. */ |
65 | } while (get64(&state->state_entry_time) != state_time || | ||
66 | (state_time & XEN_RUNSTATE_UPDATE)); | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * Runstate accounting | ||
71 | */ | ||
72 | void xen_get_runstate_snapshot(struct vcpu_runstate_info *res) | ||
73 | { | ||
74 | xen_get_runstate_snapshot_cpu(res, smp_processor_id()); | ||
71 | } | 75 | } |
72 | 76 | ||
73 | /* return true when a vcpu could run but has no real cpu to run on */ | 77 | /* return true when a vcpu could run but has no real cpu to run on */ |
@@ -80,8 +84,7 @@ static u64 xen_steal_clock(int cpu) | |||
80 | { | 84 | { |
81 | struct vcpu_runstate_info state; | 85 | struct vcpu_runstate_info state; |
82 | 86 | ||
83 | BUG_ON(cpu != smp_processor_id()); | 87 | xen_get_runstate_snapshot_cpu(&state, cpu); |
84 | xen_get_runstate_snapshot(&state); | ||
85 | return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline]; | 88 | return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline]; |
86 | } | 89 | } |
87 | 90 | ||
@@ -98,11 +101,14 @@ void xen_setup_runstate_info(int cpu) | |||
98 | 101 | ||
99 | void __init xen_time_setup_guest(void) | 102 | void __init xen_time_setup_guest(void) |
100 | { | 103 | { |
104 | bool xen_runstate_remote; | ||
105 | |||
106 | xen_runstate_remote = !HYPERVISOR_vm_assist(VMASST_CMD_enable, | ||
107 | VMASST_TYPE_runstate_update_flag); | ||
108 | |||
101 | pv_time_ops.steal_clock = xen_steal_clock; | 109 | pv_time_ops.steal_clock = xen_steal_clock; |
102 | 110 | ||
103 | static_key_slow_inc(¶virt_steal_enabled); | 111 | static_key_slow_inc(¶virt_steal_enabled); |
104 | /* | 112 | if (xen_runstate_remote) |
105 | * We can't set paravirt_steal_rq_enabled as this would require the | 113 | static_key_slow_inc(¶virt_steal_rq_enabled); |
106 | * capability to read another cpu's runstate info. | ||
107 | */ | ||
108 | } | 114 | } |