Using VIRT_CPU_ACCOUNTING, ia64 utilize "timestamp at end of iowait"
like s390.

Not-Tested-by: Hidetoshi Seto <seto.hideto...@jp.fujitsu.com>
---
 arch/ia64/include/asm/cputime.h |    2 +
 arch/ia64/kernel/time.c         |   43 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h
index e2d3f5b..6089cbd 100644
--- a/arch/ia64/include/asm/cputime.h
+++ b/arch/ia64/include/asm/cputime.h
@@ -24,6 +24,8 @@
 # include <asm/processor.h>
 # include <asm-generic/cputime_nsecs.h>
 extern void arch_vtime_task_switch(struct task_struct *tsk);
+extern void ia64_record_iowait_exit(int cpu);
+# define arch_record_iowait_exit(cpu) ia64_record_iowait_exit(cpu)
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 
 #endif /* __IA64_CPUTIME_H */
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 71c52bc..37c907d 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -138,9 +138,50 @@ void vtime_account_system(struct task_struct *tsk)
 }
 EXPORT_SYMBOL_GPL(vtime_account_system);
 
+/*
+ * Nasty trick to account iowait time as defined
+ */
+DEFINE_PER_CPU(u64, ia64_iowait_exit);
+
+void ia64_record_iowait_exit(int cpu)
+{
+       /* FIXME: ITC might not synchronized between cpus/sockets */
+        per_cpu(ia64_iowait_exit, cpu) = ia64_get_itc();
+}
+
 void vtime_account_idle(struct task_struct *tsk)
 {
-       account_idle_time(vtime_delta(tsk));
+       struct thread_info *ti = task_thread_info(tsk);
+       cputime_t delta_stime, iowait_time;
+       __u64 now;
+
+       WARN_ON_ONCE(!irqs_disabled());
+
+       now = ia64_get_itc();
+
+       /*
+        * tsk must be idle process: its runtime is accumulated as system time
+        * (ac_utime must be 0) so convert it to idle time for accounting.
+        *
+        * in cycles:
+        *                            iowait_exit
+        *  (idle_enter)              |   ac_stamp   now(=idle_exit)
+        * -------+-------------------*------+------->
+        *         <------- ac_stime ------->
+        *
+        * in cputime:
+        *       (0)
+        * -------+-------------------*------+------->
+        *         <----------- delta_stime --------->
+        *         <-- iowait_time -->
+        */
+       delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
+       iowait_time = cycle_to_cputime(ti->ac_stime +
+                       __ia64_per_cpu_var(ia64_iowait_exit) - ti->ac_stamp);
+       ti->ac_stime = 0;
+       ti->ac_stamp = now;
+
+       account_idle_and_iowait(0, iowait_time, delta_stime);
 }
 
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to