summaryrefslogtreecommitdiff
path: root/arch/ia64/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/time.c')
-rw-r--r--arch/ia64/kernel/time.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 71775b95d6cc..faa116822c4c 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -21,6 +21,7 @@
#include <linux/timex.h>
#include <linux/timekeeper_internal.h>
#include <linux/platform_device.h>
+#include <linux/cputime.h>
#include <asm/machvec.h>
#include <asm/delay.h>
@@ -59,18 +60,43 @@ static struct clocksource *itc_clocksource;
#include <linux/kernel_stat.h>
-extern cputime_t cycle_to_cputime(u64 cyc);
+extern u64 cycle_to_nsec(u64 cyc);
-void vtime_account_user(struct task_struct *tsk)
+void vtime_flush(struct task_struct *tsk)
{
- cputime_t delta_utime;
struct thread_info *ti = task_thread_info(tsk);
+ u64 delta;
- if (ti->ac_utime) {
- delta_utime = cycle_to_cputime(ti->ac_utime);
- account_user_time(tsk, delta_utime);
- ti->ac_utime = 0;
+ if (ti->utime)
+ account_user_time(tsk, cycle_to_nsec(ti->utime));
+
+ if (ti->gtime)
+ account_guest_time(tsk, cycle_to_nsec(ti->gtime));
+
+ if (ti->idle_time)
+ account_idle_time(cycle_to_nsec(ti->idle_time));
+
+ if (ti->stime) {
+ delta = cycle_to_nsec(ti->stime);
+ account_system_index_time(tsk, delta, CPUTIME_SYSTEM);
+ }
+
+ if (ti->hardirq_time) {
+ delta = cycle_to_nsec(ti->hardirq_time);
+ account_system_index_time(tsk, delta, CPUTIME_IRQ);
+ }
+
+ if (ti->softirq_time) {
+ delta = cycle_to_nsec(ti->softirq_time));
+ account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ);
}
+
+ ti->utime = 0;
+ ti->gtime = 0;
+ ti->idle_time = 0;
+ ti->stime = 0;
+ ti->hardirq_time = 0;
+ ti->softirq_time = 0;
}
/*
@@ -83,7 +109,7 @@ void arch_vtime_task_switch(struct task_struct *prev)
struct thread_info *pi = task_thread_info(prev);
struct thread_info *ni = task_thread_info(current);
- pi->ac_stamp = ni->ac_stamp;
+ ni->ac_stamp = pi->ac_stamp;
ni->ac_stime = ni->ac_utime = 0;
}
@@ -91,18 +117,15 @@ void arch_vtime_task_switch(struct task_struct *prev)
* Account time for a transition between system, hard irq or soft irq state.
* Note that this function is called with interrupts enabled.
*/
-static cputime_t vtime_delta(struct task_struct *tsk)
+static __u64 vtime_delta(struct task_struct *tsk)
{
struct thread_info *ti = task_thread_info(tsk);
- cputime_t delta_stime;
- __u64 now;
+ __u64 now, delta_stime;
WARN_ON_ONCE(!irqs_disabled());
now = ia64_get_itc();
-
- delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
- ti->ac_stime = 0;
+ delta_stime = now - ti->ac_stamp;
ti->ac_stamp = now;
return delta_stime;
@@ -110,15 +133,25 @@ static cputime_t vtime_delta(struct task_struct *tsk)
void vtime_account_system(struct task_struct *tsk)
{
- cputime_t delta = vtime_delta(tsk);
-
- account_system_time(tsk, 0, delta);
+ struct thread_info *ti = task_thread_info(tsk);
+ __u64 stime = vtime_delta(tsk);
+
+ if ((tsk->flags & PF_VCPU) && !irq_count())
+ ti->gtime += stime;
+ else if (hardirq_count())
+ ti->hardirq_time += stime;
+ else if (in_serving_softirq())
+ ti->softirq_time += stime;
+ else
+ ti->stime += stime;
}
EXPORT_SYMBOL_GPL(vtime_account_system);
void vtime_account_idle(struct task_struct *tsk)
{
- account_idle_time(vtime_delta(tsk));
+ struct thread_info *ti = task_thread_info(tsk);
+
+ ti->idle_time += vtime_delta(tsk);
}
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */