diff options
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) | |||
175 | } while (unlikely(ret != lcycle)); | 175 | } while (unlikely(ret != lcycle)); |
176 | } | 176 | } |
177 | 177 | ||
178 | /* based on xen_sched_clock() in arch/x86/xen/time.c. */ | ||
179 | /* | ||
180 | * This relies on HAVE_UNSTABLE_SCHED_CLOCK. If it can't be defined, | ||
181 | * something similar logic should be implemented here. | ||
182 | */ | ||
183 | /* | ||
184 | * Xen sched_clock implementation. Returns the number of unstolen | ||
185 | * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED | ||
186 | * states. | ||
187 | */ | ||
188 | static unsigned long long xen_sched_clock(void) | ||
189 | { | ||
190 | struct vcpu_runstate_info runstate; | ||
191 | |||
192 | unsigned long long now; | ||
193 | unsigned long long offset; | ||
194 | unsigned long long ret; | ||
195 | |||
196 | /* | ||
197 | * Ideally sched_clock should be called on a per-cpu basis | ||
198 | * anyway, so preempt should already be disabled, but that's | ||
199 | * not current practice at the moment. | ||
200 | */ | ||
201 | preempt_disable(); | ||
202 | |||
203 | /* | ||
204 | * both ia64_native_sched_clock() and xen's runstate are | ||
205 | * based on mAR.ITC. So difference of them makes sense. | ||
206 | */ | ||
207 | now = ia64_native_sched_clock(); | ||
208 | |||
209 | get_runstate_snapshot(&runstate); | ||
210 | |||
211 | WARN_ON(runstate.state != RUNSTATE_running); | ||
212 | |||
213 | offset = 0; | ||
214 | if (now > runstate.state_entry_time) | ||
215 | offset = now - runstate.state_entry_time; | ||
216 | ret = runstate.time[RUNSTATE_blocked] + | ||
217 | runstate.time[RUNSTATE_running] + | ||
218 | offset; | ||
219 | |||
220 | preempt_enable(); | ||
221 | |||
222 | return ret; | ||
223 | } | ||
224 | |||
178 | struct pv_time_ops xen_time_ops __initdata = { | 225 | struct pv_time_ops xen_time_ops __initdata = { |
179 | .init_missing_ticks_accounting = xen_init_missing_ticks_accounting, | 226 | .init_missing_ticks_accounting = xen_init_missing_ticks_accounting, |
180 | .do_steal_accounting = xen_do_steal_accounting, | 227 | .do_steal_accounting = xen_do_steal_accounting, |
181 | .clocksource_resume = xen_itc_jitter_data_reset, | 228 | .clocksource_resume = xen_itc_jitter_data_reset, |
229 | .sched_clock = xen_sched_clock, | ||
182 | }; | 230 | }; |
183 | 231 | ||
184 | /* Called after suspend, to resume time. */ | 232 | /* Called after suspend, to resume time. */ |