aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2009-03-04 07:05:40 -0500
committerTony Luck <tony.luck@intel.com>2009-03-26 13:50:42 -0400
commitf927da178671a824cf6c530f0623544206387e57 (patch)
treefb9178ff79bfd9ee3b396ff20018eacbfb222d47 /arch
parent496203b15b7249599712525c2b6aafe231b4628d (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>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/include/asm/paravirt.h7
-rw-r--r--arch/ia64/include/asm/timex.h1
-rw-r--r--arch/ia64/kernel/head.S10
-rw-r--r--arch/ia64/kernel/paravirt.c1
-rw-r--r--arch/ia64/kernel/time.c9
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
230extern struct pv_time_ops pv_time_ops; 232extern 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
247static 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
42extern void ia64_cpu_local_tick (void); 42extern void ia64_cpu_local_tick (void);
43extern 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 */
1053GLOBAL_ENTRY(sched_clock) 1053GLOBAL_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
1069END(sched_clock) 1069END(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
1074sched_clock = ia64_native_sched_clock
1075#endif
1070 1076
1071#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1077#ifdef CONFIG_VIRT_CPU_ACCOUNTING
1072GLOBAL_ENTRY(cycle_to_cputime) 1078GLOBAL_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
367struct pv_time_ops pv_time_ops = { 367struct 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 */
55unsigned long long sched_clock(void)
56{
57 return paravirt_sched_clock();
58}
59#endif
60
61#ifdef CONFIG_PARAVIRT
53static void 62static void
54paravirt_clocksource_resume(void) 63paravirt_clocksource_resume(void)
55{ 64{