Commit 40565b5a authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Ingo Molnar

sched/cputime, powerpc, s390: Make scaled cputime arch specific

Only s390 and powerpc have hardware facilities allowing to measure
cputimes scaled by frequency. On all other architectures
utimescaled/stimescaled are equal to utime/stime (however they are
accounted separately).

Remove {u,s}timescaled accounting on all architectures except
powerpc and s390, where those values are explicitly accounted
in the proper places.
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Michael Neuling <mikey@neuling.org>
Cc: Paul Mackerras <paulus@ozlabs.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20161031162143.GB12646@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 981ee2d4
...@@ -512,6 +512,9 @@ config HAVE_CONTEXT_TRACKING ...@@ -512,6 +512,9 @@ config HAVE_CONTEXT_TRACKING
config HAVE_VIRT_CPU_ACCOUNTING config HAVE_VIRT_CPU_ACCOUNTING
bool bool
config ARCH_HAS_SCALED_CPUTIME
bool
config HAVE_VIRT_CPU_ACCOUNTING_GEN config HAVE_VIRT_CPU_ACCOUNTING_GEN
bool bool
default y if 64BIT default y if 64BIT
......
...@@ -68,7 +68,7 @@ void vtime_account_user(struct task_struct *tsk) ...@@ -68,7 +68,7 @@ void vtime_account_user(struct task_struct *tsk)
if (ti->ac_utime) { if (ti->ac_utime) {
delta_utime = cycle_to_cputime(ti->ac_utime); delta_utime = cycle_to_cputime(ti->ac_utime);
account_user_time(tsk, delta_utime, delta_utime); account_user_time(tsk, delta_utime);
ti->ac_utime = 0; ti->ac_utime = 0;
} }
} }
...@@ -112,7 +112,7 @@ void vtime_account_system(struct task_struct *tsk) ...@@ -112,7 +112,7 @@ void vtime_account_system(struct task_struct *tsk)
{ {
cputime_t delta = vtime_delta(tsk); cputime_t delta = vtime_delta(tsk);
account_system_time(tsk, 0, delta, delta); account_system_time(tsk, 0, delta);
} }
EXPORT_SYMBOL_GPL(vtime_account_system); EXPORT_SYMBOL_GPL(vtime_account_system);
......
...@@ -160,6 +160,7 @@ config PPC ...@@ -160,6 +160,7 @@ config PPC
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_AUTOPROBE
select HAVE_VIRT_CPU_ACCOUNTING select HAVE_VIRT_CPU_ACCOUNTING
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_HARDENED_USERCOPY
select HAVE_KERNEL_GZIP select HAVE_KERNEL_GZIP
......
...@@ -358,7 +358,8 @@ void vtime_account_system(struct task_struct *tsk) ...@@ -358,7 +358,8 @@ void vtime_account_system(struct task_struct *tsk)
unsigned long delta, sys_scaled, stolen; unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen); delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_system_time(tsk, 0, delta, sys_scaled); account_system_time(tsk, 0, delta);
tsk->stimescaled += sys_scaled;
if (stolen) if (stolen)
account_steal_time(stolen); account_steal_time(stolen);
} }
...@@ -391,7 +392,8 @@ void vtime_account_user(struct task_struct *tsk) ...@@ -391,7 +392,8 @@ void vtime_account_user(struct task_struct *tsk)
acct->user_time = 0; acct->user_time = 0;
acct->user_time_scaled = 0; acct->user_time_scaled = 0;
acct->utime_sspurr = 0; acct->utime_sspurr = 0;
account_user_time(tsk, utime, utimescaled); account_user_time(tsk, utime);
tsk->utimescaled += utimescaled;
} }
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
......
...@@ -171,6 +171,7 @@ config S390 ...@@ -171,6 +171,7 @@ config S390
select SYSCTL_EXCEPTION_TRACE select SYSCTL_EXCEPTION_TRACE
select TTY select TTY
select VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING
select ARCH_HAS_SCALED_CPUTIME
select VIRT_TO_BUS select VIRT_TO_BUS
select HAVE_NMI select HAVE_NMI
......
...@@ -137,8 +137,10 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) ...@@ -137,8 +137,10 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
user_scaled = (user_scaled * mult) / div; user_scaled = (user_scaled * mult) / div;
system_scaled = (system_scaled * mult) / div; system_scaled = (system_scaled * mult) / div;
} }
account_user_time(tsk, user, user_scaled); account_user_time(tsk, user);
account_system_time(tsk, hardirq_offset, system, system_scaled); tsk->utimescaled += user_scaled;
account_system_time(tsk, hardirq_offset, system);
tsk->stimescaled += system_scaled;
steal = S390_lowcore.steal_timer; steal = S390_lowcore.steal_timer;
if ((s64) steal > 0) { if ((s64) steal > 0) {
...@@ -202,7 +204,8 @@ void vtime_account_irq_enter(struct task_struct *tsk) ...@@ -202,7 +204,8 @@ void vtime_account_irq_enter(struct task_struct *tsk)
system_scaled = (system_scaled * mult) / div; system_scaled = (system_scaled * mult) / div;
} }
account_system_time(tsk, 0, system, system_scaled); account_system_time(tsk, 0, system);
tsk->stimescaled += system_scaled;
virt_timer_forward(system); virt_timer_forward(system);
} }
......
...@@ -78,8 +78,8 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu) ...@@ -78,8 +78,8 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
return kstat_cpu(cpu).irqs_sum; return kstat_cpu(cpu).irqs_sum;
} }
extern void account_user_time(struct task_struct *, cputime_t, cputime_t); extern void account_user_time(struct task_struct *, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t);
extern void account_steal_time(cputime_t); extern void account_steal_time(cputime_t);
extern void account_idle_time(cputime_t); extern void account_idle_time(cputime_t);
......
...@@ -1647,7 +1647,10 @@ struct task_struct { ...@@ -1647,7 +1647,10 @@ struct task_struct {
int __user *set_child_tid; /* CLONE_CHILD_SETTID */ int __user *set_child_tid; /* CLONE_CHILD_SETTID */
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
cputime_t utime, stime, utimescaled, stimescaled; cputime_t utime, stime;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
cputime_t utimescaled, stimescaled;
#endif
cputime_t gtime; cputime_t gtime;
struct prev_cputime prev_cputime; struct prev_cputime prev_cputime;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
...@@ -2240,8 +2243,6 @@ struct task_struct *try_get_task_struct(struct task_struct **ptask); ...@@ -2240,8 +2243,6 @@ struct task_struct *try_get_task_struct(struct task_struct **ptask);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
extern void task_cputime(struct task_struct *t, extern void task_cputime(struct task_struct *t,
cputime_t *utime, cputime_t *stime); cputime_t *utime, cputime_t *stime);
extern void task_cputime_scaled(struct task_struct *t,
cputime_t *utimescaled, cputime_t *stimescaled);
extern cputime_t task_gtime(struct task_struct *t); extern cputime_t task_gtime(struct task_struct *t);
#else #else
static inline void task_cputime(struct task_struct *t, static inline void task_cputime(struct task_struct *t,
...@@ -2253,6 +2254,13 @@ static inline void task_cputime(struct task_struct *t, ...@@ -2253,6 +2254,13 @@ static inline void task_cputime(struct task_struct *t,
*stime = t->stime; *stime = t->stime;
} }
static inline cputime_t task_gtime(struct task_struct *t)
{
return t->gtime;
}
#endif
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
static inline void task_cputime_scaled(struct task_struct *t, static inline void task_cputime_scaled(struct task_struct *t,
cputime_t *utimescaled, cputime_t *utimescaled,
cputime_t *stimescaled) cputime_t *stimescaled)
...@@ -2262,12 +2270,15 @@ static inline void task_cputime_scaled(struct task_struct *t, ...@@ -2262,12 +2270,15 @@ static inline void task_cputime_scaled(struct task_struct *t,
if (stimescaled) if (stimescaled)
*stimescaled = t->stimescaled; *stimescaled = t->stimescaled;
} }
#else
static inline cputime_t task_gtime(struct task_struct *t) static inline void task_cputime_scaled(struct task_struct *t,
cputime_t *utimescaled,
cputime_t *stimescaled)
{ {
return t->gtime; task_cputime(t, utimescaled, stimescaled);
} }
#endif #endif
extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
......
...@@ -1551,7 +1551,9 @@ static __latent_entropy struct task_struct *copy_process( ...@@ -1551,7 +1551,9 @@ static __latent_entropy struct task_struct *copy_process(
init_sigpending(&p->pending); init_sigpending(&p->pending);
p->utime = p->stime = p->gtime = 0; p->utime = p->stime = p->gtime = 0;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
p->utimescaled = p->stimescaled = 0; p->utimescaled = p->stimescaled = 0;
#endif
prev_cputime_init(&p->prev_cputime); prev_cputime_init(&p->prev_cputime);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
......
...@@ -128,16 +128,13 @@ static inline void task_group_account_field(struct task_struct *p, int index, ...@@ -128,16 +128,13 @@ static inline void task_group_account_field(struct task_struct *p, int index,
* Account user cpu time to a process. * Account user cpu time to a process.
* @p: the process that the cpu time gets accounted to * @p: the process that the cpu time gets accounted to
* @cputime: the cpu time spent in user space since the last update * @cputime: the cpu time spent in user space since the last update
* @cputime_scaled: cputime scaled by cpu frequency
*/ */
void account_user_time(struct task_struct *p, cputime_t cputime, void account_user_time(struct task_struct *p, cputime_t cputime)
cputime_t cputime_scaled)
{ {
int index; int index;
/* Add user time to process. */ /* Add user time to process. */
p->utime += cputime; p->utime += cputime;
p->utimescaled += cputime_scaled;
account_group_user_time(p, cputime); account_group_user_time(p, cputime);
index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER; index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
...@@ -153,16 +150,13 @@ void account_user_time(struct task_struct *p, cputime_t cputime, ...@@ -153,16 +150,13 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
* Account guest cpu time to a process. * Account guest cpu time to a process.
* @p: the process that the cpu time gets accounted to * @p: the process that the cpu time gets accounted to
* @cputime: the cpu time spent in virtual machine since the last update * @cputime: the cpu time spent in virtual machine since the last update
* @cputime_scaled: cputime scaled by cpu frequency
*/ */
static void account_guest_time(struct task_struct *p, cputime_t cputime, static void account_guest_time(struct task_struct *p, cputime_t cputime)
cputime_t cputime_scaled)
{ {
u64 *cpustat = kcpustat_this_cpu->cpustat; u64 *cpustat = kcpustat_this_cpu->cpustat;
/* Add guest time to process. */ /* Add guest time to process. */
p->utime += cputime; p->utime += cputime;
p->utimescaled += cputime_scaled;
account_group_user_time(p, cputime); account_group_user_time(p, cputime);
p->gtime += cputime; p->gtime += cputime;
...@@ -180,16 +174,13 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime, ...@@ -180,16 +174,13 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
* Account system cpu time to a process and desired cpustat field * Account system cpu time to a process and desired cpustat field
* @p: the process that the cpu time gets accounted to * @p: the process that the cpu time gets accounted to
* @cputime: the cpu time spent in kernel space since the last update * @cputime: the cpu time spent in kernel space since the last update
* @cputime_scaled: cputime scaled by cpu frequency * @index: pointer to cpustat field that has to be updated
* @target_cputime64: pointer to cpustat field that has to be updated
*/ */
static inline static inline
void __account_system_time(struct task_struct *p, cputime_t cputime, void __account_system_time(struct task_struct *p, cputime_t cputime, int index)
cputime_t cputime_scaled, int index)
{ {
/* Add system time to process. */ /* Add system time to process. */
p->stime += cputime; p->stime += cputime;
p->stimescaled += cputime_scaled;
account_group_system_time(p, cputime); account_group_system_time(p, cputime);
/* Add system time to cpustat. */ /* Add system time to cpustat. */
...@@ -204,15 +195,14 @@ void __account_system_time(struct task_struct *p, cputime_t cputime, ...@@ -204,15 +195,14 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
* @p: the process that the cpu time gets accounted to * @p: the process that the cpu time gets accounted to
* @hardirq_offset: the offset to subtract from hardirq_count() * @hardirq_offset: the offset to subtract from hardirq_count()
* @cputime: the cpu time spent in kernel space since the last update * @cputime: the cpu time spent in kernel space since the last update
* @cputime_scaled: cputime scaled by cpu frequency
*/ */
void account_system_time(struct task_struct *p, int hardirq_offset, void account_system_time(struct task_struct *p, int hardirq_offset,
cputime_t cputime, cputime_t cputime_scaled) cputime_t cputime)
{ {
int index; int index;
if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
account_guest_time(p, cputime, cputime_scaled); account_guest_time(p, cputime);
return; return;
} }
...@@ -223,7 +213,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset, ...@@ -223,7 +213,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
else else
index = CPUTIME_SYSTEM; index = CPUTIME_SYSTEM;
__account_system_time(p, cputime, cputime_scaled, index); __account_system_time(p, cputime, index);
} }
/* /*
...@@ -410,15 +400,15 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick, ...@@ -410,15 +400,15 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
* So, we have to handle it separately here. * So, we have to handle it separately here.
* Also, p->stime needs to be updated for ksoftirqd. * Also, p->stime needs to be updated for ksoftirqd.
*/ */
__account_system_time(p, cputime, cputime, CPUTIME_SOFTIRQ); __account_system_time(p, cputime, CPUTIME_SOFTIRQ);
} else if (user_tick) { } else if (user_tick) {
account_user_time(p, cputime, cputime); account_user_time(p, cputime);
} else if (p == rq->idle) { } else if (p == rq->idle) {
account_idle_time(cputime); account_idle_time(cputime);
} else if (p->flags & PF_VCPU) { /* System time or guest time */ } else if (p->flags & PF_VCPU) { /* System time or guest time */
account_guest_time(p, cputime, cputime); account_guest_time(p, cputime);
} else { } else {
__account_system_time(p, cputime, cputime, CPUTIME_SYSTEM); __account_system_time(p, cputime, CPUTIME_SYSTEM);
} }
} }
...@@ -521,9 +511,9 @@ void account_process_tick(struct task_struct *p, int user_tick) ...@@ -521,9 +511,9 @@ void account_process_tick(struct task_struct *p, int user_tick)
cputime -= steal; cputime -= steal;
if (user_tick) if (user_tick)
account_user_time(p, cputime, cputime); account_user_time(p, cputime);
else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET))
account_system_time(p, HARDIRQ_OFFSET, cputime, cputime); account_system_time(p, HARDIRQ_OFFSET, cputime);
else else
account_idle_time(cputime); account_idle_time(cputime);
} }
...@@ -744,7 +734,7 @@ static void __vtime_account_system(struct task_struct *tsk) ...@@ -744,7 +734,7 @@ static void __vtime_account_system(struct task_struct *tsk)
{ {
cputime_t delta_cpu = get_vtime_delta(tsk); cputime_t delta_cpu = get_vtime_delta(tsk);
account_system_time(tsk, irq_count(), delta_cpu, delta_cpu); account_system_time(tsk, irq_count(), delta_cpu);
} }
void vtime_account_system(struct task_struct *tsk) void vtime_account_system(struct task_struct *tsk)
...@@ -765,7 +755,7 @@ void vtime_account_user(struct task_struct *tsk) ...@@ -765,7 +755,7 @@ void vtime_account_user(struct task_struct *tsk)
tsk->vtime_snap_whence = VTIME_SYS; tsk->vtime_snap_whence = VTIME_SYS;
if (vtime_delta(tsk)) { if (vtime_delta(tsk)) {
delta_cpu = get_vtime_delta(tsk); delta_cpu = get_vtime_delta(tsk);
account_user_time(tsk, delta_cpu, delta_cpu); account_user_time(tsk, delta_cpu);
} }
write_seqcount_end(&tsk->vtime_seqcount); write_seqcount_end(&tsk->vtime_seqcount);
} }
...@@ -921,25 +911,4 @@ void task_cputime(struct task_struct *t, cputime_t *utime, cputime_t *stime) ...@@ -921,25 +911,4 @@ void task_cputime(struct task_struct *t, cputime_t *utime, cputime_t *stime)
if (stime) if (stime)
*stime += sdelta; *stime += sdelta;
} }
void task_cputime_scaled(struct task_struct *t,
cputime_t *utimescaled, cputime_t *stimescaled)
{
cputime_t udelta, sdelta;
if (!vtime_accounting_enabled()) {
if (utimescaled)
*utimescaled = t->utimescaled;
if (stimescaled)
*stimescaled = t->stimescaled;
return;
}
fetch_task_cputime(t, utimescaled, stimescaled,
&t->utimescaled, &t->stimescaled, &udelta, &sdelta);
if (utimescaled)
*utimescaled += udelta;
if (stimescaled)
*stimescaled += sdelta;
}
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment