sched/cputime, vtime: Return nsecs instead of cputime_t to account

Turn the full dynticks cputime clock source to return nsec while keeping
its very internals jiffies based for performance reasons.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Wanpeng Li <wanpeng.li@hotmail.com>
Link: http://lkml.kernel.org/r/1485832191-26889-27-git-send-email-fweisbec@gmail.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Frederic Weisbecker 2017-01-31 04:09:42 +01:00 committed by Ingo Molnar
parent 2b1f967d80
commit bfce1d6006

View File

@ -678,20 +678,20 @@ void thread_group_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st)
#endif /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
static cputime_t vtime_delta(struct task_struct *tsk) static u64 vtime_delta(struct task_struct *tsk)
{ {
unsigned long now = READ_ONCE(jiffies); unsigned long now = READ_ONCE(jiffies);
if (time_before(now, (unsigned long)tsk->vtime_snap)) if (time_before(now, (unsigned long)tsk->vtime_snap))
return 0; return 0;
return jiffies_to_cputime(now - tsk->vtime_snap); return jiffies_to_nsecs(now - tsk->vtime_snap);
} }
static cputime_t get_vtime_delta(struct task_struct *tsk) static u64 get_vtime_delta(struct task_struct *tsk)
{ {
unsigned long now = READ_ONCE(jiffies); unsigned long now = READ_ONCE(jiffies);
cputime_t delta, other; u64 delta, other;
/* /*
* Unlike tick based timing, vtime based timing never has lost * Unlike tick based timing, vtime based timing never has lost
@ -700,7 +700,7 @@ static cputime_t get_vtime_delta(struct task_struct *tsk)
* elapsed time. Limit account_other_time to prevent rounding * elapsed time. Limit account_other_time to prevent rounding
* errors from causing elapsed vtime to go negative. * errors from causing elapsed vtime to go negative.
*/ */
delta = jiffies_to_cputime(now - tsk->vtime_snap); delta = jiffies_to_nsecs(now - tsk->vtime_snap);
other = account_other_time(delta); other = account_other_time(delta);
WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE); WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE);
tsk->vtime_snap = now; tsk->vtime_snap = now;
@ -710,9 +710,7 @@ static cputime_t get_vtime_delta(struct task_struct *tsk)
static void __vtime_account_system(struct task_struct *tsk) static void __vtime_account_system(struct task_struct *tsk)
{ {
cputime_t delta_cpu = get_vtime_delta(tsk); account_system_time(tsk, irq_count(), get_vtime_delta(tsk));
account_system_time(tsk, irq_count(), cputime_to_nsecs(delta_cpu));
} }
void vtime_account_system(struct task_struct *tsk) void vtime_account_system(struct task_struct *tsk)
@ -727,15 +725,10 @@ void vtime_account_system(struct task_struct *tsk)
void vtime_account_user(struct task_struct *tsk) void vtime_account_user(struct task_struct *tsk)
{ {
cputime_t delta_cpu;
write_seqcount_begin(&tsk->vtime_seqcount); write_seqcount_begin(&tsk->vtime_seqcount);
tsk->vtime_snap_whence = VTIME_SYS; tsk->vtime_snap_whence = VTIME_SYS;
if (vtime_delta(tsk)) { if (vtime_delta(tsk))
u64 nsecs; account_user_time(tsk, get_vtime_delta(tsk));
delta_cpu = get_vtime_delta(tsk);
account_user_time(tsk, cputime_to_nsecs(delta_cpu));
}
write_seqcount_end(&tsk->vtime_seqcount); write_seqcount_end(&tsk->vtime_seqcount);
} }
@ -776,9 +769,7 @@ EXPORT_SYMBOL_GPL(vtime_guest_exit);
void vtime_account_idle(struct task_struct *tsk) void vtime_account_idle(struct task_struct *tsk)
{ {
cputime_t delta_cpu = get_vtime_delta(tsk); account_idle_time(get_vtime_delta(tsk));
account_idle_time(cputime_to_nsecs(delta_cpu));
} }
void arch_vtime_task_switch(struct task_struct *prev) void arch_vtime_task_switch(struct task_struct *prev)
@ -818,7 +809,7 @@ u64 task_gtime(struct task_struct *t)
gtime = t->gtime; gtime = t->gtime;
if (t->vtime_snap_whence == VTIME_SYS && t->flags & PF_VCPU) if (t->vtime_snap_whence == VTIME_SYS && t->flags & PF_VCPU)
gtime += cputime_to_nsecs(vtime_delta(t)); gtime += vtime_delta(t);
} while (read_seqcount_retry(&t->vtime_seqcount, seq)); } while (read_seqcount_retry(&t->vtime_seqcount, seq));
@ -851,7 +842,7 @@ void task_cputime(struct task_struct *t, u64 *utime, u64 *stime)
if (t->vtime_snap_whence == VTIME_INACTIVE || is_idle_task(t)) if (t->vtime_snap_whence == VTIME_INACTIVE || is_idle_task(t))
continue; continue;
delta = cputime_to_nsecs(vtime_delta(t)); delta = vtime_delta(t);
/* /*
* Task runs either in user or kernel space, add pending nohz time to * Task runs either in user or kernel space, add pending nohz time to