diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2009-03-04 07:05:40 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-03-26 13:50:42 -0400 |
commit | f927da178671a824cf6c530f0623544206387e57 (patch) | |
tree | fb9178ff79bfd9ee3b396ff20018eacbfb222d47 | |
parent | 496203b15b7249599712525c2b6aafe231b4628d (diff) |
ia64/pv_ops/pv_time_ops: add sched_clock hook.
add sched_clock() hook to paravirtualize sched_clock().
ia64 sched_clock() is based on ar.itc which isn't stable
on virtualized environment because vcpu may move around on
pcpus. So it needs paravirtualization.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/ia64/include/asm/paravirt.h | 7 | ||||
-rw-r--r-- | arch/ia64/include/asm/timex.h | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/head.S | 10 | ||||
-rw-r--r-- | arch/ia64/kernel/paravirt.c | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 9 |
5 files changed, 26 insertions, 2 deletions
diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 56f69f938cca..a73e77add7e2 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h | |||
@@ -225,6 +225,8 @@ struct pv_time_ops { | |||
225 | int (*do_steal_accounting)(unsigned long *new_itm); | 225 | int (*do_steal_accounting)(unsigned long *new_itm); |
226 | 226 | ||
227 | void (*clocksource_resume)(void); | 227 | void (*clocksource_resume)(void); |
228 | |||
229 | unsigned long long (*sched_clock)(void); | ||
228 | }; | 230 | }; |
229 | 231 | ||
230 | extern struct pv_time_ops pv_time_ops; | 232 | extern struct pv_time_ops pv_time_ops; |
@@ -242,6 +244,11 @@ paravirt_do_steal_accounting(unsigned long *new_itm) | |||
242 | return pv_time_ops.do_steal_accounting(new_itm); | 244 | return pv_time_ops.do_steal_accounting(new_itm); |
243 | } | 245 | } |
244 | 246 | ||
247 | static inline unsigned long long paravirt_sched_clock(void) | ||
248 | { | ||
249 | return pv_time_ops.sched_clock(); | ||
250 | } | ||
251 | |||
245 | #endif /* !__ASSEMBLY__ */ | 252 | #endif /* !__ASSEMBLY__ */ |
246 | 253 | ||
247 | #else | 254 | #else |
diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h index 4e03cfe74a0c..86c7db861180 100644 --- a/arch/ia64/include/asm/timex.h +++ b/arch/ia64/include/asm/timex.h | |||
@@ -40,5 +40,6 @@ get_cycles (void) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | extern void ia64_cpu_local_tick (void); | 42 | extern void ia64_cpu_local_tick (void); |
43 | extern unsigned long long ia64_native_sched_clock (void); | ||
43 | 44 | ||
44 | #endif /* _ASM_IA64_TIMEX_H */ | 45 | #endif /* _ASM_IA64_TIMEX_H */ |
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 59301c472800..23f846de62d5 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S | |||
@@ -1050,7 +1050,7 @@ END(ia64_delay_loop) | |||
1050 | * except that the multiplication and the shift are done with 128-bit | 1050 | * except that the multiplication and the shift are done with 128-bit |
1051 | * intermediate precision so that we can produce a full 64-bit result. | 1051 | * intermediate precision so that we can produce a full 64-bit result. |
1052 | */ | 1052 | */ |
1053 | GLOBAL_ENTRY(sched_clock) | 1053 | GLOBAL_ENTRY(ia64_native_sched_clock) |
1054 | addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 | 1054 | addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 |
1055 | mov.m r9=ar.itc // fetch cycle-counter (35 cyc) | 1055 | mov.m r9=ar.itc // fetch cycle-counter (35 cyc) |
1056 | ;; | 1056 | ;; |
@@ -1066,7 +1066,13 @@ GLOBAL_ENTRY(sched_clock) | |||
1066 | ;; | 1066 | ;; |
1067 | shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT | 1067 | shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT |
1068 | br.ret.sptk.many rp | 1068 | br.ret.sptk.many rp |
1069 | END(sched_clock) | 1069 | END(ia64_native_sched_clock) |
1070 | #ifndef CONFIG_PARAVIRT | ||
1071 | //unsigned long long | ||
1072 | //sched_clock(void) __attribute__((alias("ia64_native_sched_clock"))); | ||
1073 | .global sched_clock | ||
1074 | sched_clock = ia64_native_sched_clock | ||
1075 | #endif | ||
1070 | 1076 | ||
1071 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 1077 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
1072 | GLOBAL_ENTRY(cycle_to_cputime) | 1078 | GLOBAL_ENTRY(cycle_to_cputime) |
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index 9f14c16f6369..6bc33a6db755 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c | |||
@@ -366,4 +366,5 @@ ia64_native_do_steal_accounting(unsigned long *new_itm) | |||
366 | 366 | ||
367 | struct pv_time_ops pv_time_ops = { | 367 | struct pv_time_ops pv_time_ops = { |
368 | .do_steal_accounting = ia64_native_do_steal_accounting, | 368 | .do_steal_accounting = ia64_native_do_steal_accounting, |
369 | .sched_clock = ia64_native_sched_clock, | ||
369 | }; | 370 | }; |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index f0ebb342409d..c323c7b9c775 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -50,6 +50,15 @@ EXPORT_SYMBOL(last_cli_ip); | |||
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #ifdef CONFIG_PARAVIRT | 52 | #ifdef CONFIG_PARAVIRT |
53 | /* We need to define a real function for sched_clock, to override the | ||
54 | weak default version */ | ||
55 | unsigned long long sched_clock(void) | ||
56 | { | ||
57 | return paravirt_sched_clock(); | ||
58 | } | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_PARAVIRT | ||
53 | static void | 62 | static void |
54 | paravirt_clocksource_resume(void) | 63 | paravirt_clocksource_resume(void) |
55 | { | 64 | { |