diff options
-rw-r--r-- | arch/ia64/kernel/paravirt.c | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 23 | ||||
-rw-r--r-- | include/asm-ia64/paravirt.h | 32 |
3 files changed, 70 insertions, 0 deletions
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index ba5383be03cb..afaf5b9a2cf0 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c | |||
@@ -352,3 +352,18 @@ struct pv_irq_ops pv_irq_ops = { | |||
352 | 352 | ||
353 | .resend_irq = ia64_native_resend_irq, | 353 | .resend_irq = ia64_native_resend_irq, |
354 | }; | 354 | }; |
355 | |||
356 | /*************************************************************************** | ||
357 | * pv_time_ops | ||
358 | * time operations | ||
359 | */ | ||
360 | |||
361 | static int | ||
362 | ia64_native_do_steal_accounting(unsigned long *new_itm) | ||
363 | { | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | struct pv_time_ops pv_time_ops = { | ||
368 | .do_steal_accounting = ia64_native_do_steal_accounting, | ||
369 | }; | ||
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 8c73643f2d66..046ca89efc05 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/machvec.h> | 24 | #include <asm/machvec.h> |
25 | #include <asm/delay.h> | 25 | #include <asm/delay.h> |
26 | #include <asm/hw_irq.h> | 26 | #include <asm/hw_irq.h> |
27 | #include <asm/paravirt.h> | ||
27 | #include <asm/ptrace.h> | 28 | #include <asm/ptrace.h> |
28 | #include <asm/sal.h> | 29 | #include <asm/sal.h> |
29 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
@@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip); | |||
48 | 49 | ||
49 | #endif | 50 | #endif |
50 | 51 | ||
52 | #ifdef CONFIG_PARAVIRT | ||
53 | static void | ||
54 | paravirt_clocksource_resume(void) | ||
55 | { | ||
56 | if (pv_time_ops.clocksource_resume) | ||
57 | pv_time_ops.clocksource_resume(); | ||
58 | } | ||
59 | #endif | ||
60 | |||
51 | static struct clocksource clocksource_itc = { | 61 | static struct clocksource clocksource_itc = { |
52 | .name = "itc", | 62 | .name = "itc", |
53 | .rating = 350, | 63 | .rating = 350, |
@@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = { | |||
56 | .mult = 0, /*to be calculated*/ | 66 | .mult = 0, /*to be calculated*/ |
57 | .shift = 16, | 67 | .shift = 16, |
58 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 68 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
69 | #ifdef CONFIG_PARAVIRT | ||
70 | .resume = paravirt_clocksource_resume, | ||
71 | #endif | ||
59 | }; | 72 | }; |
60 | static struct clocksource *itc_clocksource; | 73 | static struct clocksource *itc_clocksource; |
61 | 74 | ||
@@ -156,6 +169,9 @@ timer_interrupt (int irq, void *dev_id) | |||
156 | 169 | ||
157 | profile_tick(CPU_PROFILING); | 170 | profile_tick(CPU_PROFILING); |
158 | 171 | ||
172 | if (paravirt_do_steal_accounting(&new_itm)) | ||
173 | goto skip_process_time_accounting; | ||
174 | |||
159 | while (1) { | 175 | while (1) { |
160 | update_process_times(user_mode(get_irq_regs())); | 176 | update_process_times(user_mode(get_irq_regs())); |
161 | 177 | ||
@@ -185,6 +201,8 @@ timer_interrupt (int irq, void *dev_id) | |||
185 | local_irq_disable(); | 201 | local_irq_disable(); |
186 | } | 202 | } |
187 | 203 | ||
204 | skip_process_time_accounting: | ||
205 | |||
188 | do { | 206 | do { |
189 | /* | 207 | /* |
190 | * If we're too close to the next clock tick for | 208 | * If we're too close to the next clock tick for |
@@ -334,6 +352,11 @@ ia64_init_itm (void) | |||
334 | */ | 352 | */ |
335 | clocksource_itc.rating = 50; | 353 | clocksource_itc.rating = 50; |
336 | 354 | ||
355 | paravirt_init_missing_ticks_accounting(smp_processor_id()); | ||
356 | |||
357 | /* avoid softlock up message when cpu is unplug and plugged again. */ | ||
358 | touch_softlockup_watchdog(); | ||
359 | |||
337 | /* Setup the CPU local timer tick */ | 360 | /* Setup the CPU local timer tick */ |
338 | ia64_cpu_local_tick(); | 361 | ia64_cpu_local_tick(); |
339 | 362 | ||
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h index ee15646b6d66..1b4df129f579 100644 --- a/include/asm-ia64/paravirt.h +++ b/include/asm-ia64/paravirt.h | |||
@@ -200,6 +200,35 @@ ia64_resend_irq(unsigned int vector) | |||
200 | pv_irq_ops.resend_irq(vector); | 200 | pv_irq_ops.resend_irq(vector); |
201 | } | 201 | } |
202 | 202 | ||
203 | /****************************************************************************** | ||
204 | * replacement of time operations. | ||
205 | */ | ||
206 | |||
207 | extern struct itc_jitter_data_t itc_jitter_data; | ||
208 | extern volatile int time_keeper_id; | ||
209 | |||
210 | struct pv_time_ops { | ||
211 | void (*init_missing_ticks_accounting)(int cpu); | ||
212 | int (*do_steal_accounting)(unsigned long *new_itm); | ||
213 | |||
214 | void (*clocksource_resume)(void); | ||
215 | }; | ||
216 | |||
217 | extern struct pv_time_ops pv_time_ops; | ||
218 | |||
219 | static inline void | ||
220 | paravirt_init_missing_ticks_accounting(int cpu) | ||
221 | { | ||
222 | if (pv_time_ops.init_missing_ticks_accounting) | ||
223 | pv_time_ops.init_missing_ticks_accounting(cpu); | ||
224 | } | ||
225 | |||
226 | static inline int | ||
227 | paravirt_do_steal_accounting(unsigned long *new_itm) | ||
228 | { | ||
229 | return pv_time_ops.do_steal_accounting(new_itm); | ||
230 | } | ||
231 | |||
203 | #endif /* !__ASSEMBLY__ */ | 232 | #endif /* !__ASSEMBLY__ */ |
204 | 233 | ||
205 | #else | 234 | #else |
@@ -215,6 +244,9 @@ ia64_resend_irq(unsigned int vector) | |||
215 | #define paravirt_arch_setup_nomca() 0 | 244 | #define paravirt_arch_setup_nomca() 0 |
216 | #define paravirt_post_smp_prepare_boot_cpu() do { } while (0) | 245 | #define paravirt_post_smp_prepare_boot_cpu() do { } while (0) |
217 | 246 | ||
247 | #define paravirt_init_missing_ticks_accounting(cpu) do { } while (0) | ||
248 | #define paravirt_do_steal_accounting(new_itm) 0 | ||
249 | |||
218 | #endif /* __ASSEMBLY__ */ | 250 | #endif /* __ASSEMBLY__ */ |
219 | 251 | ||
220 | 252 | ||